E: jwoithe@physics.adelaide.edu.au
W: http://www.physics.adelaide.edu.au/~jwoithe
D: ALS-007 sound card extensions to Sound Blaster driver
-S: 4/36 Trevelyan St
-S: Wayville SA 5034
+S: 20 Jordan St
+S: Valley View, SA 5093
S: Australia
N: Clifford Wolf
(the one containing the directory /) cannot be a module, so saying M
could be dangerous. If unsure, say N.
+PReP residual data support
+CONFIG_PREP_RESIDUAL
+ Some PReP systems have residual data passed to the kernel by the
+ firmware. This allows detection of memory size, devices present and
+ other useful pieces of information. Sometimes this information is not
+ present or incorrect.
+
+ Unless you expect to boot on a PReP system, there is not need to select
+ yes.
+
/proc file system support
CONFIG_PROC_FS
This is a virtual file system providing information about the status
say M here and read Documentation/modules.txt. The module will be
called msbusmouse.o.
+Apple Desktop Bus support
+CONFIG_ADB
+ Apple Desktop Bus (ADB) support is for support of devices which
+ are connected to the to an ADB port. ADB devices tend to have
+ 4 pins. If you have an Apple Macintosh prior to the iMac, or a
+ "Blue and White G3", you probably want to say Y here. Otherwise
+ say N.
+
Apple Desktop Bus mouse support
CONFIG_ADBMOUSE
Say Y here if you have this type of bus mouse (4 pin connector) as
Processor Type
CONFIG_6xx
There are four types of PowerPC chips supported. The more common
- types (601, 603, 604, 740, 750), the Motorola embedded versions
- (821, 823, 850, 855, 860), the IBM embedded versions (403 and
+ types (601, 603, 604, 740, 750, 7400), the Motorola embedded versions
+ (821, 823, 850, 855, 860, 8260), the IBM embedded versions (403 and
405) and the high end 64 bit Power processors (Power 3, Power 4).
- Unless you are building a kernel for one of the embedded
- processor systems, or a 64 bit IBM RS/6000, choose 6xx. Note that
- the kernel runs in 32-bit mode even on 64-bit chips.
+ Unless you are building a kernel for one of the embedded processor
+ systems, or a 64 bit IBM RS/6000, choose 6xx. Note that the kernel
+ runs in 32-bit mode even on 64-bit chips. Also note that because
+ the 82xx family has a 603e core, specific support for that chipset
+ is asked later on.
+
+Motorola MPC8260 CPM support
+CONFIG_8260
+ The MPC8260 CPM (Communications Processor Module) is a typically
+ embedded CPU made by Motorola. Selecting this option means that
+ you wish to build a kernel for a machine with specifically an 8260
+ for a CPU.
+
+ If in doubt, say N.
+
+Workarounds for PPC601 bugs
+CONFIG_PPC601_SYNC_FIX
+ Some versions of the PPC601 (the first PowerPC chip) have bugs which
+ mean that extra synchronization instructions are required near certain
+ instructions, typically those that make major changes to the CPU state.
+ These extra instructions reduce performance slightly. If you say N
+ here, these extra instructions will not be included, resulting in a
+ kernel which will run faster but may not run at all on some systems
+ with the PPC601 chip.
+
+ If in doubt, say Y here.
Machine Type
-CONFIG_PMAC
+CONFIG_ALL_PPC
Linux currently supports several different kinds of PowerPC-based
machines: Apple Power Macintoshes and clones (such as the Motorola
Starmax series), PReP (PowerPC Reference Platform) machines such as
- the Motorola PowerStack, Amiga Power-Up systems (APUS), CHRP and the
- embedded MBX boards from Motorola. Currently, a single kernel binary
- only supports one type or the other. However, there is very early
- work on support for CHRP, PReP and PowerMac's from a single binary.
+ the Motorola PowerStack, CHRP (Common Hardware Reference Platform),
+ the embedded MBX boards from Motorola and many others. Currently,
+ the default option is to build a kernel which works on the first
+ three. Support for other machines is currently incomplete.
Power management support for PowerBooks
CONFIG_PMAC_PBOOK
an image of the device tree that the kernel copies from Open
Firmware. If unsure, say Y here.
+RTAS proc interface
+CONFIG_PPC_RTAS
+ When you use this option, you will be able to use RTAS from
+ userspace.
+
+ RTAS stands for RunTime Abstraction Services and should
+ provide a portable way to access and set system information. This is
+ commonly used on RS/6000 (pSeries) computers.
+
+ You can access RTAS via the special proc filesystem entry rtas.
+ Don't confuse this rtas entry with the one in /proc/device-tree/rtas
+ which is readonly.
+
+ If you don't know if you can use RTAS look into
+ /proc/device-tree/rtas. If there are some entries, it is very likely
+ that you will be able to use RTAS.
+
+ You can do cool things with rtas. To print out information about
+ various sensors in the system, just do a
+
+ $ cat /proc/rtas/sensors
+
+ or if you power off your machine at night but want it running when
+ you enter your office at 7:45 am, do a
+
+ # date -d 'tomorrow 7:30' +%s > /proc/rtas/poweron
+
+ and shutdown.
+
+ If unsure, say Y
+
MESH (Power Mac internal SCSI) support
CONFIG_SCSI_MESH
Many Power Macintoshes and clones have a MESH (Macintosh Enhanced
whenever you want). If you want to compile it as a module, say M
here and read Documentation/modules.txt.
+Use AAUI port instead of TP by default
+CONFIG_MACE_AAUI_PORT
+ Some Apple machines (notably the Apple Network Server) which use the
+ MACE ethernet chip have an Apple AUI port (small 15-pin connector),
+ instead of an 8-pin RJ45 connector for twisted-pair ethernet. Say
+ Y here if you have such a machine. If unsure, say N.
+ The driver will default to AAUI on ANS anyway, and if you use it as
+ a module, you can provide the port_aaui=0|1 to force the driver
+ setting.
+
BMAC (G3 ethernet) support
CONFIG_BMAC
Say Y for support of BMAC Ethernet interfaces. These are used on G3
!Iinclude/linux/init.h
</sect1>
- <sect1><title>Atomics</title>
+ <sect1><title>Atomic and pointer manipulation</title>
!Iinclude/asm-i386/atomic.h
+!Iinclude/asm-i386/unaligned.h
</sect1>
<sect1><title>Delaying, scheduling, and timer routines</title>
-----------------------
Maintained by Geert Uytterhoeven <geert@linux-m68k.org>
-Last revised: January 2, 2000
+Last revised: May 10, 2001
0. Introduction
For more specific information about the frame buffer device and its
applications, please refer to the Linux-fbdev website:
- http://www.linux-fbdev.org/
+ http://linux-fbdev.sourceforge.net/
and to the following documentation:
8. Mailing list
---------------
-There's a _development_ mailing list at linux-fbdev@vuser.vu.union.edu,
-controlled by majordomo. Send an email with `help' in the message body to
-majordomo@vuser.vu.union.edu for subscription information.
+There are several frame buffer device related mailing lists at SourceForge:
+ - linux-fbdev-announce@lists.sourceforge.net, for announcements,
+ - linux-fbdev-user@lists.sourceforge.net, for generic user support,
+ - linux-fbdev-devel@lists.sourceforge.net, for project developers.
-The mailing list is archived at
-
- http://www.mail-archive.com/linux-fbdev@vuser.vu.union.edu/
+Point your web browser to http://sourceforge.net/projects/linux-fbdev/ for
+subscription information and archive browsing.
9. Downloading
you will see login prompts appear on your 3270s as soon as
boot is complete (or with emulated 3270s, as soon as you dial
into your vm guest using the command "DIAL <vmguestname>").
- Since the line-mode major number is 212, the line to add to
+ Since the line-mode major number is 227, the line to add to
/etc/modules.conf should be:
- alias char-major-212 tub3270
+ alias char-major-227 tub3270
3. Define graphic devices to your vm guest machine, if you
haven't already. Define them before you reboot (reipl):
C. Are the device special files created, as in installation
step 2 above? Use the ls -l command to find out; for instance,
issue "ls -l /dev/3270/tty620". The output should start with the
- letter "c" meaning character device and should contain "212, 1"
+ letter "c" meaning character device and should contain "227, 1"
just to the left of the device name. No such file? no "c"?
Wrong major number? Wrong minor number? There's your
problem!
You send a BREAK, then within 5 seconds a command key. Sending
BREAK twice is interpreted as a normal BREAK.
-On Mac - Press 'Keypad+-F13-<command key>'
+On PowerPC - Press 'ALT - Print Screen (or F13) - <command key>,
+ Print Screen (or F13) - <command key> may suffice.
On other - If you know of the key combos for other architectures, please
let me know so I can add them to this section.
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 5
-EXTRAVERSION =-pre5
+EXTRAVERSION =-pre6
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
Wildfire CONFIG_ALPHA_WILDFIRE" Generic
# clear all implied options (don't want default values for those):
-unset CONFIG_ALPHA_EV4 CONFIG_ALPHA_EV5 CONFIG_ALPHA_EV6 CONFIG_ALPHA_EV67
+unset CONFIG_ALPHA_EV4 CONFIG_ALPHA_EV5 CONFIG_ALPHA_EV6
unset CONFIG_ALPHA_EISA
unset CONFIG_ALPHA_LCA CONFIG_ALPHA_APECS CONFIG_ALPHA_CIA
unset CONFIG_ALPHA_T2 CONFIG_ALPHA_PYXIS CONFIG_ALPHA_POLARIS
then
define_bool CONFIG_ALPHA_EV6 y
define_bool CONFIG_ALPHA_TSUNAMI y
- bool 'EV67 (or later) CPU (speed > 600MHz)?' CONFIG_ALPHA_EV67
fi
if [ "$CONFIG_ALPHA_WILDFIRE" = "y" -o "$CONFIG_ALPHA_TITAN" = "y" ]
then
define_bool CONFIG_ALPHA_EV6 y
- define_bool CONFIG_ALPHA_EV67 y
fi
if [ "$CONFIG_ALPHA_RAWHIDE" = "y" ]
then
then
define_bool CONFIG_ALPHA_IRONGATE y
define_bool CONFIG_ALPHA_EV6 y
- define_bool CONFIG_ALPHA_EV67 y
fi
if [ "$CONFIG_ALPHA_JENSEN" = "y" -o "$CONFIG_ALPHA_MIKASA" = "y" \
bool 'Symmetric multi-processing support' CONFIG_SMP
fi
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ bool 'Discontiguous Memory Support' CONFIG_DISCONTIGMEM
+ if [ "$CONFIG_DISCONTIGMEM" = "y" ]; then
+ bool ' NUMA Support' CONFIG_NUMA
+ fi
+fi
+
# The machine must be able to support more than 8GB physical memory
# before large vmalloc might even pretend to be an issue.
if [ "$CONFIG_ALPHA_GENERIC" = "y" -o "$CONFIG_ALPHA_DP264" = "y" \
EXPORT_SYMBOL(flush_tlb_all);
EXPORT_SYMBOL(flush_tlb_mm);
EXPORT_SYMBOL(flush_tlb_range);
+EXPORT_SYMBOL(flush_tlb_page);
EXPORT_SYMBOL(smp_imb);
EXPORT_SYMBOL(cpu_data);
EXPORT_SYMBOL(__cpu_number_map);
EXPORT_SYMBOL_NOVERS(memset);
EXPORT_SYMBOL(get_wchan);
-EXPORT_SYMBOL(flush_tlb_page);
}
/*
- * Fixup attempt number 1.
- *
- * Write zeros directly into the tag registers.
+ * On PYXIS, even if the tbia works, we cannot use it. It effectively locks
+ * the chip (as well as direct write to the tag registers) if there is a
+ * SG DMA operation in progress. This is true at least for PYXIS rev. 1,
+ * so always use the method below.
*/
-
-static void
-cia_pci_tbi_try1(struct pci_controller *hose,
- dma_addr_t start, dma_addr_t end)
-{
- wmb();
- *(vip)CIA_IOC_TB_TAGn(0) = 0;
- *(vip)CIA_IOC_TB_TAGn(1) = 0;
- *(vip)CIA_IOC_TB_TAGn(2) = 0;
- *(vip)CIA_IOC_TB_TAGn(3) = 0;
- *(vip)CIA_IOC_TB_TAGn(4) = 0;
- *(vip)CIA_IOC_TB_TAGn(5) = 0;
- *(vip)CIA_IOC_TB_TAGn(6) = 0;
- *(vip)CIA_IOC_TB_TAGn(7) = 0;
- mb();
- *(vip)CIA_IOC_TB_TAGn(0);
-}
-
-#if 0
/*
- * Fixup attempt number 2. This is the method NT and NetBSD use.
+ * This is the method NT and NetBSD use.
*
* Allocate mappings, and put the chip into DMA loopback mode to read a
* garbage page. This works by causing TLB misses, causing old entries to
* be purged to make room for the new entries coming in for the garbage page.
*/
-#define CIA_BROKEN_TBI_TRY2_BASE 0xE0000000
-
-static void __init
-cia_enable_broken_tbi_try2(void)
-{
- unsigned long *ppte, pte;
- long i;
-
- ppte = __alloc_bootmem(PAGE_SIZE, 32768, 0);
- pte = (virt_to_phys(ppte) >> (PAGE_SHIFT - 1)) | 1;
-
- for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); ++i)
- ppte[i] = pte;
+#define CIA_BROKEN_TBIA_BASE 0xE0000000
+#define CIA_BROKEN_TBIA_SIZE 1024
- *(vip)CIA_IOC_PCI_W3_BASE = CIA_BROKEN_TBI_TRY2_BASE | 3;
- *(vip)CIA_IOC_PCI_W3_MASK = (PAGE_SIZE - 1) & 0xfff00000;
- *(vip)CIA_IOC_PCI_T3_BASE = virt_to_phys(ppte) >> 2;
-}
-
-static void
+/* Always called with interrupts disabled */
+void
cia_pci_tbi_try2(struct pci_controller *hose,
dma_addr_t start, dma_addr_t end)
{
- unsigned long flags;
unsigned long bus_addr;
int ctrl;
- long i;
-
- __save_and_cli(flags);
/* Put the chip into PCI loopback mode. */
mb();
TLB entries are not quite LRU, meaning that we need to read more
times than there are actual tags. The 2117x docs claim strict
round-robin. Oh well, we've come this far... */
+ /* Even better - as seen on the PYXIS rev 1 the TLB tags 0-3 can
+ be filled by the TLB misses *only once* after being invalidated
+ (by tbia or direct write). Next misses won't update them even
+ though the lock bits are cleared. Tags 4-7 are "quite LRU" though,
+ so use them and read at window 3 base exactly 4 times. Reading
+ more sometimes makes the chip crazy. -ink */
+
+ bus_addr = cia_ioremap(CIA_BROKEN_TBIA_BASE);
- bus_addr = cia_ioremap(CIA_BROKEN_TBI_TRY2_BASE);
- for (i = 0; i < 12; ++i, bus_addr += 32768)
- cia_readl(bus_addr);
+ cia_readl(bus_addr + 0x00000);
+ cia_readl(bus_addr + 0x08000);
+ cia_readl(bus_addr + 0x10000);
+ cia_readl(bus_addr + 0x18000);
/* Restore normal PCI operation. */
mb();
mb();
*(vip)CIA_IOC_CIA_CTRL;
mb();
+}
- __restore_flags(flags);
+static inline void
+cia_prepare_tbia_workaround(void)
+{
+ unsigned long *ppte, pte;
+ long i;
+
+ /* Use minimal 1K map. */
+ ppte = __alloc_bootmem(CIA_BROKEN_TBIA_SIZE, 32768, 0);
+ pte = (virt_to_phys(ppte) >> (PAGE_SHIFT - 1)) | 1;
+
+ for (i = 0; i < CIA_BROKEN_TBIA_SIZE / sizeof(unsigned long); ++i)
+ ppte[i] = pte;
+
+ *(vip)CIA_IOC_PCI_W3_BASE = CIA_BROKEN_TBIA_BASE | 3;
+ *(vip)CIA_IOC_PCI_W3_MASK = (CIA_BROKEN_TBIA_SIZE*1024 - 1)
+ & 0xfff00000;
+ *(vip)CIA_IOC_PCI_T3_BASE = virt_to_phys(ppte) >> 2;
}
-#endif
static void __init
verify_tb_operation(void)
struct pci_iommu_arena *arena = pci_isa_hose->sg_isa;
int ctrl, addr0, tag0, pte0, data0;
- int temp;
+ int temp, use_tbia_try2 = 0;
+
+ /* pyxis -- tbia is broken */
+ if (pci_isa_hose->dense_io_base)
+ use_tbia_try2 = 1;
/* Put the chip into PCI loopback mode. */
mb();
/* Third, try to invalidate the TLB. */
- cia_pci_tbi(arena->hose, 0, -1);
- temp = *(vip)CIA_IOC_TB_TAGn(0);
- if (temp & 1) {
- cia_pci_tbi_try1(arena->hose, 0, -1);
-
+ if (! use_tbia_try2) {
+ cia_pci_tbi(arena->hose, 0, -1);
temp = *(vip)CIA_IOC_TB_TAGn(0);
if (temp & 1) {
- printk("pci: failed tbia test; "
- "no usable workaround\n");
- goto failed;
+ use_tbia_try2 = 1;
+ printk("pci: failed tbia test; workaround available\n");
+ } else {
+ printk("pci: passed tbia test\n");
}
-
- alpha_mv.mv_pci_tbi = cia_pci_tbi_try1;
- printk("pci: failed tbia test; workaround 1 succeeded\n");
- } else {
- printk("pci: passed tbia test\n");
}
/* Fourth, verify the TLB snoops the EV5's caches when
/* Clean up after the tests. */
arena->ptes[4] = 0;
arena->ptes[5] = 0;
+
+ if (use_tbia_try2) {
+ alpha_mv.mv_pci_tbi = cia_pci_tbi_try2;
+
+ /* Tags 0-3 must be disabled if we use this workaraund. */
+ wmb();
+ *(vip)CIA_IOC_TB_TAGn(0) = 2;
+ *(vip)CIA_IOC_TB_TAGn(1) = 2;
+ *(vip)CIA_IOC_TB_TAGn(2) = 2;
+ *(vip)CIA_IOC_TB_TAGn(3) = 2;
+
+ printk("pci: tbia workaround enabled\n");
+ }
alpha_mv.mv_pci_tbi(arena->hose, 0, -1);
exit:
*(vip)CIA_IOC_PCI_W2_MASK = (0x40000000 - 1) & 0xfff00000;
*(vip)CIA_IOC_PCI_T2_BASE = 0x40000000 >> 2;
- *(vip)CIA_IOC_PCI_W3_BASE = 0;
+ /* Prepare workaround for apparently broken tbia. */
+ cia_prepare_tbia_workaround();
}
void __init
#include <linux/pci.h>
#include <linux/sched.h>
#include <linux/init.h>
+#include <linux/bootmem.h>
#include <asm/ptrace.h>
#include <asm/system.h>
it's the shifted tag bits. */
value = (start & 0xffff0000) >> 12;
- wmb();
*csr = value;
mb();
*csr;
#define FN __FUNCTION__
+static void __init
+tsunami_monster_window_enable(tsunami_pchip * pchip)
+{
+ volatile unsigned long * csr = &pchip->pctl.csr;
+
+ *csr |= pctl_m_mwin;
+ mb();
+ *csr;
+}
+
static void __init
tsunami_init_one_pchip(tsunami_pchip *pchip, int index)
{
* address range.
*/
hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
- hose->sg_pci = iommu_arena_new(hose, 0xc0000000, 0x08000000, 0);
+ {
+ unsigned long size = 0x08000000;
+ if (max_low_pfn > (0x80000000 >> PAGE_SHIFT))
+ size = 0x40000000;
+ hose->sg_pci = iommu_arena_new(hose, 0xc0000000, size, 0);
+ }
+
__direct_map_base = 0x40000000;
__direct_map_size = 0x80000000;
pchip->tba[3].csr = virt_to_phys(hose->sg_pci->ptes);
tsunami_pci_tbi(hose, 0, -1);
+
+ /* Enable the Monster Window to make DAC pci64 possible. */
+ tsunami_monster_window_enable(pchip);
}
void __init
#define SIGCHLD 20
-#define NR_SYSCALLS 377
+#define NR_SYSCALLS 378
/*
* These offsets must match with alpha_mv in <asm/machvec.h>.
br restore_all
.end entSys
-#ifdef CONFIG_SMP
- .globl ret_from_smp_fork
+ .globl ret_from_fork
.align 3
-.ent ret_from_smp_fork
-ret_from_smp_fork:
+.ent ret_from_fork
+ret_from_fork:
lda $26,ret_from_sys_call
mov $17,$16
jsr $31,schedule_tail
-.end ret_from_smp_fork
-#endif /* CONFIG_SMP */
+.end ret_from_fork
.align 3
.ent reschedule
/* If the machine doesn't define a pci_tbi routine, we have to
assume it doesn't support sg mapping. */
if (! alpha_mv.mv_pci_tbi) {
- printk(KERN_INFO "pci_map_single failed: no hw sg\n");
+ printk(KERN_WARNING "pci_map_single failed: no hw sg\n");
return 0;
}
npages = calc_npages((paddr & ~PAGE_MASK) + size);
dma_ofs = iommu_arena_alloc(arena, npages);
if (dma_ofs < 0) {
- printk(KERN_INFO "pci_map_single failed: "
+ printk(KERN_WARNING "pci_map_single failed: "
"could not allocate dma page tables\n");
return 0;
}
pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, long size,
int direction)
{
+ unsigned long flags;
struct pci_controller *hose = pdev ? pdev->sysdata : pci_isa_hose;
struct pci_iommu_arena *arena;
long dma_ofs, npages;
}
npages = calc_npages((dma_addr & ~PAGE_MASK) + size);
+
+ spin_lock_irqsave(&arena->lock, flags);
+
iommu_arena_free(arena, dma_ofs, npages);
if (dma_ofs >= arena->next_entry)
alpha_mv.mv_pci_tbi(hose, dma_addr, dma_addr + size - 1);
+ spin_unlock_irqrestore(&arena->lock, flags);
+
DBGA("pci_unmap_single: sg [%x,%lx] np %ld from %p\n",
dma_addr, size, npages, __builtin_return_address(0));
}
/* Otherwise, break up the remaining virtually contiguous
hunks into individual direct maps. */
for (sg = leader; sg < end; ++sg)
- if (sg->dma_address == 2 || sg->dma_address == -2)
+ if (sg->dma_address == 1 || sg->dma_address == -2)
sg->dma_address = 0;
/* Retry. */
out->dma_length = 0;
if (out - start == 0)
- printk(KERN_INFO "pci_map_sg failed: no entries?\n");
+ printk(KERN_WARNING "pci_map_sg failed: no entries?\n");
DBGA("pci_map_sg: %ld entries\n", out - start);
return out - start;
error:
- printk(KERN_INFO "pci_map_sg failed: "
+ printk(KERN_WARNING "pci_map_sg failed: "
"could not allocate dma page tables\n");
/* Some allocation failed while mapping the scatterlist
pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
int direction)
{
+ unsigned long flags;
struct pci_controller *hose;
struct pci_iommu_arena *arena;
struct scatterlist *end;
arena = hose->sg_isa;
fbeg = -1, fend = 0;
+
+ spin_lock_irqsave(&arena->lock, flags);
+
for (end = sg + nents; sg < end; ++sg) {
unsigned long addr, size;
long npages, ofs;
if ((fend - arena->dma_base) >> PAGE_SHIFT >= arena->next_entry)
alpha_mv.mv_pci_tbi(hose, fbeg, fend);
+ spin_unlock_irqrestore(&arena->lock, flags);
+
DBGA("pci_unmap_sg: %d entries\n", nents - (end - sg));
}
/* Although we are an idle CPU, we do not want to
get into the scheduler unnecessarily. */
- if (current->need_resched) {
- schedule();
- check_pgt_cache();
- }
+ long oldval = xchg(¤t->need_resched, -1UL);
+ if (!oldval)
+ while (current->need_resched < 0);
+ schedule();
+ check_pgt_cache();
}
}
struct task_struct * p, struct pt_regs * regs)
{
extern void ret_from_sys_call(void);
- extern void ret_from_smp_fork(void);
+ extern void ret_from_fork(void);
struct pt_regs * childregs;
struct switch_stack * childstack, *stack;
stack = ((struct switch_stack *) regs) - 1;
childstack = ((struct switch_stack *) childregs) - 1;
*childstack = *stack;
-#ifdef CONFIG_SMP
- childstack->r26 = (unsigned long) ret_from_smp_fork;
-#else
- childstack->r26 = (unsigned long) ret_from_sys_call;
-#endif
+ childstack->r26 = (unsigned long) ret_from_fork;
p->thread.usp = usp;
p->thread.ksp = (unsigned long) childstack;
p->thread.pal_flags = 1; /* set FEN, clear everything else */
static struct alpha_machine_vector *get_sysvec_byname(const char *);
static void get_sysnames(long, long, char **, char **);
-/*
- * This is setup by the secondary bootstrap loader. Because
- * the zero page is zeroed out as soon as the vm system is
- * initialized, we need to copy things out into a more permanent
- * place.
- */
-#define PARAM ZERO_PGE
-#define COMMAND_LINE ((char*)(PARAM + 0x0000))
-#define COMMAND_LINE_SIZE 256
-#define INITRD_START (*(unsigned long *) (PARAM+0x100))
-#define INITRD_SIZE (*(unsigned long *) (PARAM+0x108))
-
static char command_line[COMMAND_LINE_SIZE];
char saved_command_line[COMMAND_LINE_SIZE];
return end >> PAGE_SHIFT; /* Return the PFN of the limit. */
}
+#ifndef CONFIG_DISCONTIGMEM
static void __init
setup_memory(void *kernel_end)
{
/* Reserve the bootmap memory. */
reserve_bootmem(PFN_PHYS(bootmap_start), bootmap_size);
+ printk("reserving pages %ld:%ld\n", bootmap_start, bootmap_start+PFN_UP(bootmap_size));
#ifdef CONFIG_BLK_DEV_INITRD
initrd_start = INITRD_START;
}
#endif /* CONFIG_BLK_DEV_INITRD */
}
+#else
+extern void setup_memory(void *);
+#endif /* !CONFIG_DISCONTIGMEM */
int __init
page_is_ram(unsigned long pfn)
cpu_data[cpuid].prof_multiplier = 1;
}
+static void __init
+wait_boot_cpu_to_stop(int cpuid)
+{
+ long stop = jiffies + 10*HZ;
+
+ while (time_before(jiffies, stop)) {
+ if (!smp_secondary_alive)
+ return;
+ barrier();
+ }
+
+ printk("wait_boot_cpu_to_stop: FAILED on CPU %d, hanging now\n", cpuid);
+ for (;;)
+ barrier();
+}
+
/*
* Where secondaries begin a life of C.
*/
{
int cpuid = hard_smp_processor_id();
+ if (current != init_tasks[cpu_number_map(cpuid)]) {
+ printk("BUG: smp_calling: cpu %d current %p init_tasks[cpu_number_map(cpuid)] %p\n",
+ cpuid, current, init_tasks[cpu_number_map(cpuid)]);
+ }
+
DBGS(("CALLIN %d state 0x%lx\n", cpuid, current->state));
/* Turn on machine checks. */
/* Must have completely accurate bogos. */
__sti();
+
+ /*
+ * Wait boot CPU to stop with irq enabled before
+ * running calibrate_delay().
+ */
+ wait_boot_cpu_to_stop(cpuid);
+ mb();
calibrate_delay();
- smp_store_cpu_info(cpuid);
- /* Allow master to continue. */
+ smp_store_cpu_info(cpuid);
+ /*
+ * Allow master to continue only after we written
+ * the loops_per_jiffy.
+ */
wmb();
- smp_secondary_alive = cpuid;
+ smp_secondary_alive = 1;
/* Wait for the go code. */
while (!smp_threads_ready)
break;
case EV6_CPU:
+ case EV67_CPU:
on_chip_cache = 64 + 64;
break;
+ hwrpb->processor_offset
+ cpuid * hwrpb->processor_size);
- cpumask = (1L << cpuid);
+ cpumask = (1UL << cpuid);
if (hwrpb->txrdy & cpumask)
goto delay1;
ready1:
return;
delay1:
- /* Wait one second. Note that jiffies aren't ticking yet. */
- for (timeout = 100000; timeout > 0; --timeout) {
+ /* Wait 10 seconds. Note that jiffies aren't ticking yet. */
+ for (timeout = 1000000; timeout > 0; --timeout) {
if (!(hwrpb->txrdy & cpumask))
goto ready1;
udelay(10);
goto timeout;
delay2:
- /* Wait one second. */
- for (timeout = 100000; timeout > 0; --timeout) {
+ /* Wait 10 seconds. */
+ for (timeout = 1000000; timeout > 0; --timeout) {
if (!(hwrpb->txrdy & cpumask))
goto ready2;
udelay(10);
mycpu = hard_smp_processor_id();
for (i = 0; i < NR_CPUS; i++) {
- if (!(txrdy & (1L << i)))
+ if (!(txrdy & (1UL << i)))
continue;
DBGS(("recv_secondary_console_msg: "
#if 0
DBGS(("KSP 0x%lx PTBR 0x%lx VPTBR 0x%lx UNIQUE 0x%lx\n",
- hwpcb->ksp, hwpcb->ptbr, hwrpb->vptb, hwcpb->unique));
+ hwpcb->ksp, hwpcb->ptbr, hwrpb->vptb, hwpcb->unique));
#endif
DBGS(("Starting secondary cpu %d: state 0x%lx pal_flags 0x%lx\n",
cpuid, idle->state, idle->thread.pal_flags));
send_secondary_console_msg("START\r\n", cpuid);
- /* Wait 1 second for an ACK from the console. Note that jiffies
+ /* Wait 10 seconds for an ACK from the console. Note that jiffies
aren't ticking yet. */
- for (timeout = 100000; timeout > 0; timeout--) {
+ for (timeout = 1000000; timeout > 0; timeout--) {
if (cpu->flags & 1)
goto started;
udelay(10);
idle = init_task.prev_task;
if (!idle)
panic("No idle process for CPU %d", cpuid);
+ if (idle == &init_task)
+ panic("idle process is init_task for CPU %d", cpuid);
idle->processor = cpuid;
__cpu_logical_map[cpunum] = cpuid;
if (secondary_cpu_start(cpuid, idle))
return -1;
+ mb();
+ /* Notify the secondary CPU it can run calibrate_delay() */
+ smp_secondary_alive = 0;
+
/* We've been acked by the console; wait one second for the task
to start up for real. Note that jiffies aren't ticking yet. */
- for (timeout = 0; timeout < 100000; timeout++) {
- if (smp_secondary_alive != -1)
+ for (timeout = 0; timeout < 1000000; timeout++) {
+ if (smp_secondary_alive == 1)
goto alive;
udelay(10);
barrier();
if ((cpu->flags & 0x1cc) == 0x1cc) {
smp_num_probed++;
/* Assume here that "whami" == index */
- hwrpb_cpu_present_mask |= (1L << i);
+ hwrpb_cpu_present_mask |= (1UL << i);
cpu->pal_revision = boot_cpu_palrev;
}
}
} else {
smp_num_probed = 1;
- hwrpb_cpu_present_mask = (1L << boot_cpuid);
+ hwrpb_cpu_present_mask = (1UL << boot_cpuid);
}
- cpu_present_mask = 1L << boot_cpuid;
+ cpu_present_mask = 1UL << boot_cpuid;
printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n",
smp_num_probed, hwrpb_cpu_present_mask);
if (smp_boot_one_cpu(i, cpu_count))
continue;
- cpu_present_mask |= 1L << i;
+ cpu_present_mask |= 1UL << i;
cpu_count++;
}
bogosum = 0;
for (i = 0; i < NR_CPUS; i++) {
- if (cpu_present_mask & (1L << i))
+ if (cpu_present_mask & (1UL << i))
bogosum += cpu_data[i].loops_per_jiffy;
}
printk(KERN_INFO "SMP: Total of %d processors activated "
printk(KERN_WARNING
"smp_send_reschedule: Sending IPI to self.\n");
#endif
- send_ipi_message(1L << cpu, IPI_RESCHEDULE);
+ send_ipi_message(1UL << cpu, IPI_RESCHEDULE);
}
void
smp_send_stop(void)
{
- unsigned long to_whom = cpu_present_mask ^ (1L << smp_processor_id());
+ unsigned long to_whom = cpu_present_mask ^ (1UL << smp_processor_id());
#if DEBUG_IPI_MSG
if (hard_smp_processor_id() != boot_cpu_id)
printk(KERN_WARNING "smp_send_stop: Not on boot cpu.\n");
int
smp_call_function (void (*func) (void *info), void *info, int retry, int wait)
{
- unsigned long to_whom = cpu_present_mask ^ (1L << smp_processor_id());
+ unsigned long to_whom = cpu_present_mask ^ (1UL << smp_processor_id());
struct smp_call_struct data;
long timeout;
int printed = 0;
int cpu = smp_processor_id();
- stuck = 1L << 28;
+ stuck = 1L << 30;
try_again:
/* Use sub-sections to put the actual loop at the end
try_again:
- stuck_lock = 1<<26;
- stuck_reader = 1<<26;
+ stuck_lock = 1<<30;
+ stuck_reader = 1<<30;
__asm__ __volatile__(
"1: ldl_l %1,%0\n"
try_again:
- stuck_lock = 1<<26;
+ stuck_lock = 1<<30;
__asm__ __volatile__(
"1: ldl_l %1,%0;"
* is interesting.
*/
printk("%6x%c", (int)tmp & 0xffffff, (++i % 11) ? ' ' : '\n');
+#if 0
if (i > 40) {
printk(" ...");
break;
}
+#endif
+ }
+ printk("\n");
+}
+
+int kstack_depth_to_print = 24;
+
+void show_stack(unsigned long *sp)
+{
+ unsigned long *stack;
+ int i;
+
+ /*
+ * debugging aid: "show_stack(NULL);" prints the
+ * back trace for this cpu.
+ */
+ if(sp==NULL)
+ sp=(unsigned long*)&sp;
+
+ stack = sp;
+ for(i=0; i < kstack_depth_to_print; i++) {
+ if (((long) stack & (THREAD_SIZE-1)) == 0)
+ break;
+ if (i && ((i % 4) == 0))
+ printk("\n ");
+ printk("%016lx ", *stack++);
}
printk("\n");
+ dik_show_trace(sp);
}
void
#
# Note 2! The CFLAGS definition is now in the main makefile...
-OBJS = init.o fault.o extable.o
+O_TARGET := mm.o
-mm.o: $(OBJS)
- $(LD) -r -o mm.o $(OBJS)
+obj-y := init.o fault.o extable.o
+
+obj-$(CONFIG_DISCONTIGMEM) += numa.o
include $(TOPDIR)/Rules.make
/* There is only the kernel to search. */
ret = search_one_table(__start___ex_table, __stop___ex_table - 1,
addr - gp);
- if (ret) return ret;
#else
+ extern spinlock_t modlist_lock;
+ unsigned long flags;
/* The kernel is the last "module" -- no need to treat it special. */
struct module *mp;
+
+ ret = 0;
+ spin_lock_irqsave(&modlist_lock, flags);
for (mp = module_list; mp ; mp = mp->next) {
- if (!mp->ex_table_start)
+ if (!mp->ex_table_start || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING)))
continue;
ret = search_one_table(mp->ex_table_start,
mp->ex_table_end - 1, addr - mp->gp);
- if (ret) return ret;
+ if (ret)
+ break;
}
+ spin_unlock_irqrestore(&modlist_lock, flags);
#endif
- return 0;
+ return ret;
}
unsigned
addr - exc_gp);
if (ret) return ret;
#else
+ extern spinlock_t modlist_lock;
+ unsigned long flags;
/* The kernel is the last "module" -- no need to treat it special. */
struct module *mp;
+
+ ret = 0;
+ spin_lock_irqsave(&modlist_lock, flags);
for (mp = module_list; mp ; mp = mp->next) {
- if (!mp->ex_table_start)
+ if (!mp->ex_table_start || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING)))
continue;
ret = search_one_table(mp->ex_table_start,
mp->ex_table_end - 1, addr - exc_gp);
- if (ret) return ret;
+ if (ret)
+ break;
}
+ spin_unlock_irqrestore(&modlist_lock, flags);
+ if (ret) return ret;
#endif
/*
#include <asm/mmu_context.h>
#include <asm/console.h>
-static unsigned long totalram_pages;
+unsigned long totalram_pages;
extern void die_if_kernel(char *,struct pt_regs *,long);
return pte_mkdirty(mk_pte(virt_to_page(EMPTY_PGE), PAGE_SHARED));
}
+#ifndef CONFIG_DISCONTIGMEM
void
show_mem(void)
{
printk("%ld pages in page table cache\n",pgtable_cache_size);
show_buffers();
}
+#endif
static inline unsigned long
load_PCB(struct thread_struct * pcb)
}
+#ifndef CONFIG_DISCONTIGMEM
/*
* paging_init() sets up the memory map.
*/
dma_pfn = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
high_pfn = max_low_pfn;
-#define ORDER_MASK (~((1L << (MAX_ORDER-1))-1))
-#define ORDER_ALIGN(n) (((n) + ~ORDER_MASK) & ORDER_MASK)
-
- dma_pfn = ORDER_ALIGN(dma_pfn);
- high_pfn = ORDER_ALIGN(high_pfn);
-
-#undef ORDER_MASK
-#undef ORDER_ALIGN
-
- if (dma_pfn > high_pfn)
+ if (dma_pfn >= high_pfn)
zones_size[ZONE_DMA] = high_pfn;
else {
zones_size[ZONE_DMA] = dma_pfn;
/* Initialize the kernel's ZERO_PGE. */
memset((void *)ZERO_PGE, 0, PAGE_SIZE);
}
+#endif /* CONFIG_DISCONTIGMEM */
#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM)
void
}
#endif
+#ifndef CONFIG_DISCONTIGMEM
static void __init
printk_memory_info(void)
{
printk_memory_info();
}
+#endif /* CONFIG_DISCONTIGMEM */
void
free_initmem (void)
void
free_initrd_mem(unsigned long start, unsigned long end)
{
+ unsigned long __start = start;
for (; start < end; start += PAGE_SIZE) {
ClearPageReserved(virt_to_page(start));
set_page_count(virt_to_page(start), 1);
free_page(start);
totalram_pages++;
}
- printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+ printk ("Freeing initrd memory: %ldk freed\n", (end - __start) >> 10);
}
#endif
--- /dev/null
+/*
+ * linux/arch/alpha/mm/numa.c
+ *
+ * DISCONTIGMEM NUMA alpha support.
+ *
+ * Copyright (C) 2001 Andrea Arcangeli <andrea@suse.de> SuSE
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/swap.h>
+#ifdef CONFIG_BLK_DEV_INITRD
+#include <linux/blk.h>
+#endif
+
+#include <asm/hwrpb.h>
+#include <asm/pgalloc.h>
+
+plat_pg_data_t *plat_node_data[MAX_NUMNODES];
+bootmem_data_t plat_node_bdata[MAX_NUMNODES];
+
+#undef DEBUG_DISCONTIG
+#ifdef DEBUG_DISCONTIG
+#define DBGDCONT(args...) printk(args)
+#else
+#define DBGDCONT(args...)
+#endif
+
+#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
+#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
+#define for_each_mem_cluster(memdesc, cluster, i) \
+ for ((cluster) = (memdesc)->cluster, (i) = 0; \
+ (i) < (memdesc)->numclusters; (i)++, (cluster)++)
+
+static void __init show_mem_layout(void)
+{
+ struct memclust_struct * cluster;
+ struct memdesc_struct * memdesc;
+ int i;
+
+ /* Find free clusters, and init and free the bootmem accordingly. */
+ memdesc = (struct memdesc_struct *)
+ (hwrpb->mddt_offset + (unsigned long) hwrpb);
+
+ printk("Raw memory layout:\n");
+ for_each_mem_cluster(memdesc, cluster, i) {
+ printk(" memcluster %2d, usage %1lx, start %8lu, end %8lu\n",
+ i, cluster->usage, cluster->start_pfn,
+ cluster->start_pfn + cluster->numpages);
+ }
+}
+
+static void __init
+setup_memory_node(int nid, void *kernel_end)
+{
+ extern unsigned long mem_size_limit;
+ struct memclust_struct * cluster;
+ struct memdesc_struct * memdesc;
+ unsigned long start_kernel_pfn, end_kernel_pfn;
+ unsigned long bootmap_size, bootmap_pages, bootmap_start;
+ unsigned long start, end;
+ unsigned long node_pfn_start, node_pfn_end;
+ int i;
+ unsigned long node_datasz = PFN_UP(sizeof(plat_pg_data_t));
+ int show_init = 0;
+
+ /* Find the bounds of current node */
+ node_pfn_start = (nid * NODE_MAX_MEM_SIZE) >> PAGE_SHIFT;
+ node_pfn_end = node_pfn_start + (NODE_MAX_MEM_SIZE >> PAGE_SHIFT);
+
+ /* Find free clusters, and init and free the bootmem accordingly. */
+ memdesc = (struct memdesc_struct *)
+ (hwrpb->mddt_offset + (unsigned long) hwrpb);
+
+ /* find the bounds of this node (min_low_pfn/max_low_pfn) */
+ min_low_pfn = ~0UL;
+ for_each_mem_cluster(memdesc, cluster, i) {
+ /* Bit 0 is console/PALcode reserved. Bit 1 is
+ non-volatile memory -- we might want to mark
+ this for later. */
+ if (cluster->usage & 3)
+ continue;
+
+ start = cluster->start_pfn;
+ end = start + cluster->numpages;
+
+ if (start >= node_pfn_end || end <= node_pfn_start)
+ continue;
+
+ if (!show_init) {
+ show_init = 1;
+ printk("Initialing bootmem allocator on Node ID %d\n", nid);
+ }
+ printk(" memcluster %2d, usage %1lx, start %8lu, end %8lu\n",
+ i, cluster->usage, cluster->start_pfn,
+ cluster->start_pfn + cluster->numpages);
+
+ if (start < node_pfn_start)
+ start = node_pfn_start;
+ if (end > node_pfn_end)
+ end = node_pfn_end;
+
+ if (start < min_low_pfn)
+ min_low_pfn = start;
+ if (end > max_low_pfn)
+ max_low_pfn = end;
+ }
+
+ if (mem_size_limit && max_low_pfn >= mem_size_limit) {
+ printk("setup: forcing memory size to %ldK (from %ldK).\n",
+ mem_size_limit << (PAGE_SHIFT - 10),
+ max_low_pfn << (PAGE_SHIFT - 10));
+ max_low_pfn = mem_size_limit;
+ }
+
+ if (min_low_pfn >= max_low_pfn)
+ return;
+
+ num_physpages += max_low_pfn - min_low_pfn;
+
+ /* Cute trick to make sure our local node data is on local memory */
+ PLAT_NODE_DATA(nid) = (plat_pg_data_t *)(__va(min_low_pfn << PAGE_SHIFT));
+ /* Quasi-mark the plat_pg_data_t as in-use */
+ min_low_pfn += node_datasz;
+ if (min_low_pfn >= max_low_pfn) {
+ printk(" not enough mem to reserve PLAT_NODE_DATA");
+ return;
+ }
+ NODE_DATA(nid)->bdata = &plat_node_bdata[nid];
+
+ printk(" Detected node memory: start %8lu, end %8lu\n",
+ min_low_pfn, max_low_pfn);
+
+ DBGDCONT(" DISCONTIG: plat_node_data[%d] is at 0x%p\n", nid, PLAT_NODE_DATA(nid));
+ DBGDCONT(" DISCONTIG: NODE_DATA(%d)->bdata is at 0x%p\n", nid, NODE_DATA(nid)->bdata);
+
+ /* Find the bounds of kernel memory. */
+ start_kernel_pfn = PFN_DOWN(KERNEL_START_PHYS);
+ end_kernel_pfn = PFN_UP(virt_to_phys(kernel_end));
+ bootmap_start = -1;
+
+ if (!nid && (max_low_pfn < end_kernel_pfn || min_low_pfn > start_kernel_pfn))
+ panic("kernel loaded out of ram");
+
+ /* Zone start phys-addr must be 2^(MAX_ORDER-1) aligned */
+ min_low_pfn = (min_low_pfn + ((1UL << (MAX_ORDER-1))-1)) & ~((1UL << (MAX_ORDER-1))-1);
+
+ /* We need to know how many physically contiguous pages
+ we'll need for the bootmap. */
+ bootmap_pages = bootmem_bootmap_pages(max_low_pfn-min_low_pfn);
+
+ /* Now find a good region where to allocate the bootmap. */
+ for_each_mem_cluster(memdesc, cluster, i) {
+ if (cluster->usage & 3)
+ continue;
+
+ start = cluster->start_pfn;
+ end = start + cluster->numpages;
+
+ if (start >= max_low_pfn || end <= min_low_pfn)
+ continue;
+
+ if (end > max_low_pfn)
+ end = max_low_pfn;
+ if (start < min_low_pfn)
+ start = min_low_pfn;
+
+ if (start < start_kernel_pfn) {
+ if (end > end_kernel_pfn
+ && end - end_kernel_pfn >= bootmap_pages) {
+ bootmap_start = end_kernel_pfn;
+ break;
+ } else if (end > start_kernel_pfn)
+ end = start_kernel_pfn;
+ } else if (start < end_kernel_pfn)
+ start = end_kernel_pfn;
+ if (end - start >= bootmap_pages) {
+ bootmap_start = start;
+ break;
+ }
+ }
+
+ if (bootmap_start == -1)
+ panic("couldn't find a contigous place for the bootmap");
+
+ /* Allocate the bootmap and mark the whole MM as reserved. */
+ bootmap_size = init_bootmem_node(NODE_DATA(nid), bootmap_start,
+ min_low_pfn, max_low_pfn);
+ DBGDCONT(" bootmap_start %lu, bootmap_size %lu, bootmap_pages %lu\n",
+ bootmap_start, bootmap_size, bootmap_pages);
+
+ /* Mark the free regions. */
+ for_each_mem_cluster(memdesc, cluster, i) {
+ if (cluster->usage & 3)
+ continue;
+
+ start = cluster->start_pfn;
+ end = cluster->start_pfn + cluster->numpages;
+
+ if (start >= max_low_pfn || end <= min_low_pfn)
+ continue;
+
+ if (end > max_low_pfn)
+ end = max_low_pfn;
+ if (start < min_low_pfn)
+ start = min_low_pfn;
+
+ if (start < start_kernel_pfn) {
+ if (end > end_kernel_pfn) {
+ free_bootmem_node(NODE_DATA(nid), PFN_PHYS(start),
+ (PFN_PHYS(start_kernel_pfn)
+ - PFN_PHYS(start)));
+ printk(" freeing pages %ld:%ld\n",
+ start, start_kernel_pfn);
+ start = end_kernel_pfn;
+ } else if (end > start_kernel_pfn)
+ end = start_kernel_pfn;
+ } else if (start < end_kernel_pfn)
+ start = end_kernel_pfn;
+ if (start >= end)
+ continue;
+
+ free_bootmem_node(NODE_DATA(nid), PFN_PHYS(start), PFN_PHYS(end) - PFN_PHYS(start));
+ printk(" freeing pages %ld:%ld\n", start, end);
+ }
+
+ /* Reserve the bootmap memory. */
+ reserve_bootmem_node(NODE_DATA(nid), PFN_PHYS(bootmap_start), bootmap_size);
+ printk(" reserving pages %ld:%ld\n", bootmap_start, bootmap_start+PFN_UP(bootmap_size));
+
+ numnodes++;
+}
+
+void __init
+setup_memory(void *kernel_end)
+{
+ int nid;
+
+ show_mem_layout();
+
+ numnodes = 0;
+ for (nid = 0; nid < MAX_NUMNODES; nid++)
+ setup_memory_node(nid, kernel_end);
+
+#ifdef CONFIG_BLK_DEV_INITRD
+ initrd_start = INITRD_START;
+ if (initrd_start) {
+ initrd_end = initrd_start+INITRD_SIZE;
+ printk("Initial ramdisk at: 0x%p (%lu bytes)\n",
+ (void *) initrd_start, INITRD_SIZE);
+
+ if ((void *)initrd_end > phys_to_virt(PFN_PHYS(max_low_pfn))) {
+ printk("initrd extends beyond end of memory "
+ "(0x%08lx > 0x%p)\ndisabling initrd\n",
+ initrd_end,
+ phys_to_virt(PFN_PHYS(max_low_pfn)));
+ initrd_start = initrd_end = 0;
+ } else {
+ /* Assume the initrd to be in the first node */
+ reserve_bootmem_node(NODE_DATA(nid), virt_to_phys((void *)initrd_start),
+ INITRD_SIZE);
+ }
+ }
+#endif /* CONFIG_BLK_DEV_INITRD */
+}
+
+void __init paging_init(void)
+{
+ unsigned int nid;
+ unsigned long zones_size[MAX_NR_ZONES] = {0, };
+ unsigned long dma_local_pfn;
+
+ /*
+ * The old global MAX_DMA_ADDRESS per-arch API doesn't fit
+ * in the NUMA model, for now we convert it to a pfn and
+ * we interpret this pfn as a local per-node information.
+ * This issue isn't very important since none of these machines
+ * have legacy ISA slots anyways.
+ */
+ dma_local_pfn = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+
+ for (nid = 0; nid < numnodes; nid++) {
+ unsigned long start_pfn = plat_node_bdata[nid].node_boot_start >> PAGE_SHIFT;
+ unsigned long end_pfn = plat_node_bdata[nid].node_low_pfn;
+ unsigned long lmax_mapnr;
+
+ if (dma_local_pfn >= end_pfn - start_pfn)
+ zones_size[ZONE_DMA] = end_pfn - start_pfn;
+ else {
+ zones_size[ZONE_DMA] = dma_local_pfn;
+ zones_size[ZONE_NORMAL] = (end_pfn - start_pfn) - dma_local_pfn;
+ }
+ free_area_init_node(nid, NODE_DATA(nid), NULL, zones_size, start_pfn<<PAGE_SHIFT, NULL);
+ lmax_mapnr = PLAT_NODE_DATA_STARTNR(nid) + PLAT_NODE_DATA_SIZE(nid);
+ if (lmax_mapnr > max_mapnr) {
+ max_mapnr = lmax_mapnr;
+ DBGDCONT("Grow max_mapnr to %ld\n", max_mapnr);
+ }
+ }
+
+ /* Initialize the kernel's ZERO_PGE. */
+ memset((void *)ZERO_PGE, 0, PAGE_SIZE);
+}
+
+#define printkdot() \
+do { \
+ if (!(i++ % ((100UL*1024*1024)>>PAGE_SHIFT))) \
+ printk("."); \
+} while(0)
+
+#define clobber(p, size) memset((p)->virtual, 0xaa, (size))
+
+void __init mem_stress(void)
+{
+ LIST_HEAD(x);
+ LIST_HEAD(xx);
+ struct page * p;
+ unsigned long i = 0;
+
+ printk("starting memstress");
+ while ((p = alloc_pages(GFP_ATOMIC, 1))) {
+ clobber(p, PAGE_SIZE*2);
+ list_add(&p->list, &x);
+ printkdot();
+ }
+ while ((p = alloc_page(GFP_ATOMIC))) {
+ clobber(p, PAGE_SIZE);
+ list_add(&p->list, &xx);
+ printkdot();
+ }
+ while (!list_empty(&x)) {
+ p = list_entry(x.next, struct page, list);
+ clobber(p, PAGE_SIZE*2);
+ list_del(x.next);
+ __free_pages(p, 1);
+ printkdot();
+ }
+ while (!list_empty(&xx)) {
+ p = list_entry(xx.next, struct page, list);
+ clobber(p, PAGE_SIZE);
+ list_del(xx.next);
+ __free_pages(p, 0);
+ printkdot();
+ }
+ printk("I'm still alive duh!\n");
+}
+
+#undef printkdot
+#undef clobber
+
+void __init mem_init(void)
+{
+ unsigned long codesize, reservedpages, datasize, initsize, pfn;
+ extern int page_is_ram(unsigned long) __init;
+ extern char _text, _etext, _data, _edata;
+ extern char __init_begin, __init_end;
+ extern unsigned long totalram_pages;
+ unsigned long nid, i;
+ mem_map_t * lmem_map;
+
+ high_memory = (void *) __va(max_mapnr <<PAGE_SHIFT);
+
+ reservedpages = 0;
+ for (nid = 0; nid < numnodes; nid++) {
+ /*
+ * This will free up the bootmem, ie, slot 0 memory
+ */
+ totalram_pages += free_all_bootmem_node(NODE_DATA(nid));
+
+ lmem_map = NODE_MEM_MAP(nid);
+ pfn = NODE_DATA(nid)->node_start_paddr >> PAGE_SHIFT;
+ for (i = 0; i < PLAT_NODE_DATA_SIZE(nid); i++, pfn++)
+ if (page_is_ram(pfn) && PageReserved(lmem_map+i))
+ reservedpages++;
+ }
+
+ codesize = (unsigned long) &_etext - (unsigned long) &_text;
+ datasize = (unsigned long) &_edata - (unsigned long) &_data;
+ initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
+
+ printk("Memory: %luk/%luk available (%luk kernel code, %luk reserved, "
+ "%luk data, %luk init)\n",
+ nr_free_pages() << (PAGE_SHIFT-10),
+ num_physpages << (PAGE_SHIFT-10),
+ codesize >> 10,
+ reservedpages << (PAGE_SHIFT-10),
+ datasize >> 10,
+ initsize >> 10);
+#if 0
+ mem_stress();
+#endif
+}
+
+void
+show_mem(void)
+{
+ long i,free = 0,total = 0,reserved = 0;
+ long shared = 0, cached = 0;
+ int nid;
+
+ printk("\nMem-info:\n");
+ show_free_areas();
+ printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
+ for (nid = 0; nid < numnodes; nid++) {
+ mem_map_t * lmem_map = NODE_MEM_MAP(nid);
+ i = PLAT_NODE_DATA_SIZE(nid);
+ while (i-- > 0) {
+ total++;
+ if (PageReserved(lmem_map+i))
+ reserved++;
+ else if (PageSwapCache(lmem_map+i))
+ cached++;
+ else if (!page_count(lmem_map+i))
+ free++;
+ else
+ shared += atomic_read(&lmem_map[i].count) - 1;
+ }
+ }
+ printk("%ld pages of RAM\n",total);
+ printk("%ld free pages\n",free);
+ printk("%ld reserved pages\n",reserved);
+ printk("%ld pages shared\n",shared);
+ printk("%ld pages swap cached\n",cached);
+ printk("%ld pages in page table cache\n",pgtable_cache_size);
+ show_buffers();
+}
Pentium-Classic CONFIG_M586TSC \
Pentium-MMX CONFIG_M586MMX \
Pentium-Pro/Celeron/Pentium-II CONFIG_M686 \
- Pentium-III/Celeron-Coppermine CONFIG_MPENTIUMIII \
+ Pentium-III/Celeron(Coppermine) CONFIG_MPENTIUMIII \
Pentium-4 CONFIG_MPENTIUM4 \
K6/K6-II/K6-III CONFIG_MK6 \
Athlon/Duron/K7 CONFIG_MK7 \
if ( ccrc[6] ) printk ("mtrr: ARR3 was write protected, unprotected\n");
} /* End Function cyrix_arr_init */
-static void __init centaur_mcr_init(void)
+/*
+ * Initialise the later (saner) Winchip MCR variant. In this version
+ * the BIOS can pass us the registers it has used (but not their values)
+ * and the control register is read/write
+ */
+
+static void __init centaur_mcr1_init(void)
{
unsigned i;
- struct set_mtrr_context ctxt;
u32 lo, hi;
- int wc2 = -1;
- set_mtrr_prepare (&ctxt);
/* Unfortunately, MCR's are read-only, so there is no way to
* find out what the bios might have done.
*/
- /*
- * Enable MCR key if we are using a winchip2
- */
-
- if(boot_cpu_data.x86_model==4)
- wc2 = 0;
-
- if(boot_cpu_data.x86_model==8 || boot_cpu_data.x86_model == 9)
+ rdmsr(0x120, lo, hi);
+ if(((lo>>17)&7)==1) /* Type 1 Winchip2 MCR */
{
- rdmsr(0x120, lo, hi);
- if(((lo>>17)&7)==1) /* Type 1 Winchip2 MCR */
- {
- lo&= ~0x1C0; /* clear key */
- lo|= 0x040; /* set key to 1 */
- wrmsr(0x120, lo, hi); /* unlock MCR */
- wc2 = 1;
- centaur_mcr_type = 1;
- }
+ lo&= ~0x1C0; /* clear key */
+ lo|= 0x040; /* set key to 1 */
+ wrmsr(0x120, lo, hi); /* unlock MCR */
}
- /* Clear any unconfigured MCR's.
- * This way we are sure that the centaur_mcr array contains the actual
- * values. The disadvantage is that any BIOS tweaks are thus undone.
- *
+
+ centaur_mcr_type = 1;
+
+ /*
+ * Clear any unconfigured MCR's.
*/
+
for (i = 0; i < 8; ++i)
{
if(centaur_mcr[i]. high == 0 && centaur_mcr[i].low == 0)
{
- if(wc2 == 0 || ( wc2 == 1 && !(lo & (1<<(9+i)))))
+ if(!(lo & (1<<(9+i))))
wrmsr (0x110 + i , 0, 0);
else
/*
centaur_mcr_reserved |= (1<<i);
}
}
- /* Throw the main write-combining switch...
- However if OOSTORE is enabled then people have already done far
- cleverer things and we should behave.
+ /*
+ * Throw the main write-combining switch...
+ * However if OOSTORE is enabled then people have already done far
+ * cleverer things and we should behave.
*/
- if(wc2 == 1)
- {
- lo |= 15; /* Write combine enables */
- wrmsr(0x120, lo, hi);
+ lo |= 15; /* Write combine enables */
+ wrmsr(0x120, lo, hi);
+} /* End Function centaur_mcr1_init */
+
+/*
+ * Initialise the original winchip with read only MCR registers
+ * no used bitmask for the BIOS to pass on and write only control
+ */
+
+static void __init centaur_mcr0_init(void)
+{
+ unsigned i;
+
+ /* Unfortunately, MCR's are read-only, so there is no way to
+ * find out what the bios might have done.
+ */
+
+ /* Clear any unconfigured MCR's.
+ * This way we are sure that the centaur_mcr array contains the actual
+ * values. The disadvantage is that any BIOS tweaks are thus undone.
+ *
+ */
+ for (i = 0; i < 8; ++i)
+ {
+ if(centaur_mcr[i]. high == 0 && centaur_mcr[i].low == 0)
+ wrmsr (0x110 + i , 0, 0);
}
- else if(wc2 == 0)
- wrmsr(0x120, 0x01F0001F, 0); /* Write only */
+
+ wrmsr(0x120, 0x01F0001F, 0); /* Write only */
+} /* End Function centaur_mcr0_init */
+
+/*
+ * Initialise Winchip series MCR registers
+ */
+
+static void __init centaur_mcr_init(void)
+{
+ struct set_mtrr_context ctxt;
+
+ set_mtrr_prepare (&ctxt);
+
+ if(boot_cpu_data.x86_model==4)
+ centaur_mcr0_init();
+ else if(boot_cpu_data.x86_model==8 || boot_cpu_data.x86_model == 9)
+ centaur_mcr1_init();
+
set_mtrr_done (&ctxt);
} /* End Function centaur_mcr_init */
endif
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
-MAKECOFFBOOT = $(MAKE) -C arch/$(ARCH)/coffboot
-MAKECHRPBOOT = $(MAKE) -C arch/$(ARCH)/chrpboot
-MAKEMBXBOOT = $(MAKE) -C arch/$(ARCH)/mbxboot
-MAKETREEBOOT = $(MAKE) -C arch/$(ARCH)/treeboot
ifdef CONFIG_8xx
SUBDIRS += arch/ppc/8xx_io
checks:
@$(MAKE) -C arch/$(ARCH)/kernel checks
-BOOT_TARGETS = zImage znetboot.initrd zImage.initrd
+BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd
-ifdef CONFIG_4xx
-$(BOOT_TARGETS): $(CHECKS) vmlinux
- @$(MAKETREEBOOT) $@
-endif
-
-ifdef CONFIG_8xx
-$(BOOT_TARGETS): $(CHECKS) vmlinux
- @$(MAKECOFFBOOT) $@
- @$(MAKEMBXBOOT) $@
-endif
-
-ifdef CONFIG_6xx
-ifndef CONFIG_8260
-$(BOOT_TARGETS): $(CHECKS) vmlinux
- @$(MAKECOFFBOOT) $@
- @$(MAKEBOOT) $@
- @$(MAKECHRPBOOT) $@
-
-znetboot: $(CHECKS) vmlinux
-ifdef CONFIG_ALL_PPC
-ifdef CONFIG_SMP
- cp -f vmlinux /tftpboot/vmlinux.smp
-else
- cp -f vmlinux /tftpboot/vmlinux
-endif
-endif
- @$(MAKECOFFBOOT) $@
- @$(MAKEBOOT) $@
- @$(MAKECHRPBOOT) $@
-else
-# 8260 is custom 6xx
-$(BOOT_TARGETS): $(CHECKS) vmlinux
- @$(MAKECOFFBOOT) $@
- @$(MAKEMBXBOOT) $@
-endif
-endif
-
-ifdef CONFIG_PPC64BRIDGE
$(BOOT_TARGETS): $(CHECKS) vmlinux
- @$(MAKECOFFBOOT) $@
@$(MAKEBOOT) $@
- @$(MAKECHRPBOOT) $@
-
-znetboot: $(CHECKS) vmlinux
- cp -f vmlinux /tftpboot/vmlinux.64
- @$(MAKECOFFBOOT) $@
- @$(MAKEBOOT) $@
- @$(MAKECHRPBOOT) $@
-endif
%_config: arch/ppc/configs/%_defconfig
rm -f .config arch/ppc/defconfig
archclean:
rm -f arch/ppc/kernel/{mk_defs,ppc_defs.h,find_name,checks}
- @$(MAKECOFFBOOT) clean
@$(MAKEBOOT) clean
- @$(MAKECHRPBOOT) clean
- @$(MAKEMBXBOOT) clean
- @$(MAKETREEBOOT) clean
archmrproper:
archdep:
- $(MAKEBOOT) fastdep
- $(MAKECHRPBOOT) fastdep
+ $(MAKEBOOT) dep
# Adapted for PowerPC by Gary Thomas
# modified by Cort (cort@cs.nmt.edu)
#
+
.c.s:
$(CC) $(CFLAGS) -S -o $*.s $<
.s.o:
$(AS) -o $*.o $<
.c.o:
- $(CC) $(CFLAGS) -DINITRD_OFFSET=$(IOFF) -DINITRD_SIZE=$(ISZ) -DZIMAGE_OFFSET=$(ZOFF) -DZIMAGE_SIZE=$(ZSZ) -D__BOOTER__ -c -o $*.o $<
+ $(CC) $(CFLAGS) -c -o $*.o $<
.S.s:
$(CPP) $(AFLAGS) -traditional -o $*.o $<
.S.o:
$(CC) $(AFLAGS) -traditional -c -o $*.o $<
-ZOFF = 0
-ZSZ = 0
-IOFF = 0
-ISZ = 0
+GZIP_FLAGS = -v9f
-ifeq ($(CONFIG_SMP),y)
-TFTPIMAGE=/tftpboot/zImage.prep.smp$(MSIZE)
-else
-TFTPIMAGE=/tftpboot/zImage.prep$(MSIZE)
-endif
+CFLAGS := $(CPPFLAGS) -O2 -DSTDC_HEADERS -fno-builtin -D__BOOTER__ \
+ -I$(TOPDIR)/arch/$(ARCH)/boot/include
+AFLAGS += -D__BOOTER__
+OBJCOPY_ARGS = -O elf32-powerpc
ifeq ($(CONFIG_SMP),y)
TFTPSIMAGE=/tftpboot/sImage.smp
TFTPSIMAGE=/tftpboot/sImage
endif
-ifeq ($(CONFIG_PPC64BRIDGE),y)
-MSIZE=.64
-else
-MSIZE=
-endif
-
-ZLINKFLAGS = -T ../vmlinux.lds -Ttext 0x00800000
-GZIP_FLAGS = -v9f
-
-OBJECTS := head.o misc.o ../coffboot/zlib.o
-CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS -fno-builtin
-OBJCOPY_ARGS = -O elf32-powerpc
-
-OBJECTS += vreset.o kbd.o of1275.o
-ifeq ($(CONFIG_SERIAL_CONSOLE),y)
-OBJECTS += ns16550.o
-endif
+lib/zlib.a:
+ $(MAKE) -C lib
-all: zImage
+images/vmlinux.gz: $(TOPDIR)/vmlinux
+ $(MAKE) -C images vmlinux.gz
-zvmlinux.initrd: zvmlinux
- $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS)
- $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
- --add-section=initrd=ramdisk.image.gz \
- --add-section=image=../coffboot/vmlinux.gz \
- zvmlinux.initrd.tmp zvmlinux.initrd
- $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd initrd` \
- -DINITRD_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd initrd` \
- -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd image` \
- -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd image` \
- -D__BOOTER__ \
- -c -o misc.o misc.c
- $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS)
- $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
- --add-section=initrd=ramdisk.image.gz \
- --add-section=image=../coffboot/vmlinux.gz \
- zvmlinux.initrd.tmp $@
- rm zvmlinux.initrd.tmp
+# Since gemini doesn't need/have it's own directory, we do znetboot* here
ifdef CONFIG_GEMINI
- $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS)
- $(OBJCOPY) -I elf32-powerpc -O binary zvmlinux.initrd.tmp svmlinux.initrd.tmp
- ./mksimage svmlinux.initrd.tmp ../coffboot/vmlinux.gz ramdisk.image.gz \
- -o svmlinux.initrd > sImage.map
- $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh sioffset initrd` \
- -DINITRD_SIZE=`sh sisize initrd` \
- -DZIMAGE_OFFSET=`sh sioffset zimage` \
- -DZIMAGE_SIZE=`sh sisize zimage` \
- -c -o misc.o misc.c
- $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS)
- $(OBJCOPY) -I elf32-powerpc -O binary zvmlinux.initrd.tmp svmlinux.initrd.tmp
- ./mksimage svmlinux.initrd.tmp ../coffboot/vmlinux.gz ramdisk.image.gz \
- -o svmlinux.initrd > /dev/null
- rm svmlinux.initrd.tmp zvmlinux.initrd.tmp sImage.map
+BOOT_TARGETS = zImage zImage.initrd
+else
+BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd
endif
-zImage: zvmlinux mkprep sImage mksimage
+# We go into the utils dir by hand to ensure HOSTCC builds
+$(BOOT_TARGETS): sImage vmapus lib/zlib.a images/vmlinux.gz
+ifneq ("xx$(CONFIG_8260)$(CONFIG_8xx)","xx")
+ $(MAKE) -C mbx $@
+endif
ifdef CONFIG_ALL_PPC
- ./mkprep -pbp zvmlinux zImage
+ $(MAKE) -C utils addnote piggyback mknote hack-coff mkprep
+ $(MAKE) -C chrp $@
+ $(MAKE) -C pmac $@
+ $(MAKE) -C prep $@
endif
-ifdef CONFIG_APUS
- $(STRIP) ../../../vmlinux -o vmapus
- gzip $(GZIP_FLAGS) vmapus
+ifdef CONFIG_4xx
+ $(MAKE) -C tree $@
endif
-sImage: ../../../vmlinux
+sImage: $(TOPDIR)/vmlinux
ifdef CONFIG_GEMINI
- $(OBJCOPY) -I elf32-powerpc -O binary ../../../vmlinux sImage
+ $(OBJCOPY) -I elf32-powerpc -O binary $(TOPDIR)/vmlinux images/sImage
endif
-zImage.initrd: zvmlinux.initrd mkprep
-ifdef CONFIG_ALL_PPC
- ./mkprep -pbp zvmlinux.initrd zImage.initrd
+vmapus: $(TOPDIR)/vmlinux
+ifdef CONFIG_APUS
+ $(STRIP) $(TOPDIR)/vmlinux -o images/vmapus
+ gzip $(GZIP_FLAGS) images/vmapus
endif
-zvmlinux: $(OBJECTS) ../coffboot/vmlinux.gz mksimage
-#
-# build the boot loader image and then compute the offset into it
-# for the kernel image
-#
- $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS)
- $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment --add-section=image=../coffboot/vmlinux.gz \
- zvmlinux.tmp $@
-#
-# then with the offset rebuild the bootloader so we know where the kernel is
-#
- $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \
- -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux image` \
- -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux image` \
- -D__BOOTER__ \
- -c -o misc.o misc.c
- $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS)
- $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment --add-section=image=../coffboot/vmlinux.gz \
- zvmlinux.tmp $@
- rm zvmlinux.tmp
ifdef CONFIG_GEMINI
- $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS)
- $(OBJCOPY) -I elf32-powerpc -O binary zvmlinux.tmp svmlinux.tmp
- ./mksimage svmlinux.tmp ../coffboot/vmlinux.gz -o svmlinux > sImage.map
- $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \
- -DZIMAGE_OFFSET=`sh sioffset zimage` \
- -DZIMAGE_SIZE=`sh sisize zimage` \
- -c -o misc.o misc.c
- $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS)
- $(OBJCOPY) -I elf32-powerpc -O binary zvmlinux.tmp svmlinux.tmp
- ./mksimage svmlinux.tmp ../coffboot/vmlinux.gz -o svmlinux > /dev/null
- rm svmlinux.tmp sImage.map zvmlinux.tmp
-endif
-
-floppy: $(TOPDIR)/vmlinux zImage
- dd if=zImage of=/dev/fd0H1440 bs=64b
-
-mkprep : mkprep.c
- $(HOSTCC) -o mkprep mkprep.c
-
-mksimage: mksimage.c
- $(HOSTCC) -o mksimage mksimage.c
-
znetboot : zImage
-ifdef CONFIG_ALL_PPC
- cp zImage $(TFTPIMAGE)
-endif
-ifdef CONFIG_GEMINI
- cp sImage $(TFTPSIMAGE)
+ cp images/sImage $(TFTPSIMAGE)
endif
-znetboot.initrd : zImage.initrd
- cp zImage.initrd $(TFTPIMAGE)
-
+# Do the dirs
clean:
- rm -f vmlinux* zvmlinux* mkprep zImage* sImage* mksimage
-
-fastdep:
- $(TOPDIR)/scripts/mkdep *.[Sch] > .depend
+ $(MAKE) -C images clean
+ $(MAKE) -C tree clean
+ $(MAKE) -C utils clean
dep:
- $(CPP) $(CPPFLAGS) -M *.S *.c > .depend
-
-# just here to match coffboot/Makefile
-vmlinux.coff:
-
-vmlinux.coff.initrd:
+ $(MAKE) -C mbx fastdep
+ $(MAKE) -C chrp fastdep
+ $(MAKE) -C common fastdep
+ $(MAKE) -C pmac fastdep
+ $(MAKE) -C prep fastdep
+ $(MAKE) -C common fastdep
+
+include $(TOPDIR)/Rules.make
--- /dev/null
+# BK Id: SCCS/s.Makefile 1.8 05/18/01 06:20:29 patch
+#
+# Makefile for making ELF bootable images for booting on CHRP
+# using Open Firmware.
+#
+# Geert Uytterhoeven September 1997
+#
+# Based on coffboot by Paul Mackerras
+
+ifeq ($(CONFIG_PPC64BRIDGE),y)
+MSIZE=.64
+AFLAGS += -Wa,-mppc64bridge
+else
+MSIZE=
+endif
+
+.c.o:
+ $(CC) $(CFLAGS) -DKERNELBASE=$(KERNELBASE) -c -o $*.o $<
+.S.o:
+ $(CC) $(AFLAGS) -traditional -c -o $*.o $<
+
+LD_ARGS = -Ttext 0x00400000
+
+OBJS = ../common/crt0.o start.o main.o misc.o ../common/string.o image.o
+LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a
+ADDNOTE = ../utils/addnote
+PIGGYBACK = ../utils/piggyback
+
+ifeq ($(CONFIG_SMP),y)
+TFTPIMAGE=/tftpboot/zImage.chrp.smp$(MSIZE)
+else
+TFTPIMAGE=/tftpboot/zImage.chrp$(MSIZE)
+endif
+
+all: zImage
+
+znetboot: zImage
+ifdef CONFIG_SMP
+ cp -f $(TOPDIR)/vmlinux /tftpboot/vmlinux.smp
+else
+ cp -f $(TOPDIR)/vmlinux /tftpboot/vmlinux
+endif
+ifdef CONFIG_PPC64BRIDGE
+ cp -f $(TOPDIR)/vmlinux /tftpboot/vmlinux.64
+endif
+ cp ../images/zImage.chrp $(TFTPIMAGE)
+
+znetboot.initrd: zImage.initrd
+ cp ../images/zImage.initrd.chrp $(TFTPIMAGE)
+
+floppy: zImage
+ mcopy zImage a:zImage
+
+image.o: $(PIGGYBACK) ../images/vmlinux.gz
+ $(PIGGYBACK) image < ../images/vmlinux.gz | $(AS) -o $@
+
+sysmap.o: $(PIGGYBACK) $(TOPDIR)/System.map
+ $(PIGGYBACK) sysmap < $(TOPDIR)/System.map | $(AS) -o $@
+
+initrd.o: ../images/ramdisk.image.gz $(PIGGYBACK)
+ $(PIGGYBACK) initrd < ../images/ramdisk.image.gz | $(AS) -o $@
+
+zImage: $(OBJS) $(LIBS) ../common/no_initrd.o $(ADDNOTE) ../images/vmlinux.gz
+ $(LD) $(LD_ARGS) -o ../images/$@.chrp $(OBJS) ../common/no_initrd.o $(LIBS)
+ cp ../images/$@.chrp ../images/$@.chrp-rs6k
+ $(ADDNOTE) ../images/$@.chrp-rs6k
+
+zImage.initrd: $(OBJS) $(LIBS) initrd.o $(ADDNOTE) ../images/vmlinux.gz
+ $(LD) $(LD_ARGS) -o ../images/$@.chrp $(OBJS) initrd.o $(LIBS)
+ cp ../images/$@.chrp ../images/$@.chrp-rs6k
+ $(ADDNOTE) ../images/$@.chrp-rs6k
+
+include $(TOPDIR)/Rules.make
--- /dev/null
+/*
+ * BK Id: SCCS/s.main.c 1.7 05/18/01 06:20:29 patch
+ */
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include "nonstdio.h"
+#include "zlib.h"
+#include <asm/bootinfo.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+
+extern void *finddevice(const char *);
+extern int getprop(void *, const char *, void *, int);
+void gunzip(void *, int, unsigned char *, int *);
+
+#define RAM_START 0x00000000
+#define RAM_END (64<<20)
+
+#define BOOT_START ((unsigned long)_start)
+#define BOOT_END ((unsigned long)(_end + 0xFFF) & ~0xFFF)
+
+#define RAM_FREE ((unsigned long)(_end+0x1000)&~0xFFF)
+#define PROG_START 0x00010000
+
+char *avail_ram;
+char *end_avail;
+
+extern char _end[];
+extern char image_data[];
+extern int image_len;
+extern char initrd_data[];
+extern int initrd_len;
+extern char sysmap_data[];
+extern int sysmap_len;
+
+static char scratch[1024<<10]; /* 1MB of scratch space for gunzip */
+
+chrpboot(int a1, int a2, void *prom)
+{
+ int ns, oh, i;
+ unsigned sa, len;
+ void *dst;
+ unsigned char *im;
+ unsigned initrd_start, initrd_size;
+ extern char _start;
+
+ printf("chrpboot starting: loaded at 0x%x\n\r", &_start);
+
+ if (initrd_len) {
+ initrd_size = initrd_len;
+ initrd_start = (RAM_END - initrd_size) & ~0xFFF;
+ a1 = initrd_start;
+ a2 = initrd_size;
+ claim(initrd_start, RAM_END - initrd_start, 0);
+ printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n\r",
+ initrd_start, initrd_data, initrd_size);
+ memcpy((char *)initrd_start, initrd_data, initrd_size);
+ }
+
+ im = image_data;
+ len = image_len;
+ /* claim 4MB starting at PROG_START */
+ claim(PROG_START, (4<<20) - PROG_START, 0);
+ dst = (void *) PROG_START;
+ if (im[0] == 0x1f && im[1] == 0x8b) {
+ avail_ram = scratch;
+ end_avail = scratch + sizeof(scratch);
+ printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
+ gunzip(dst, 0x400000, im, &len);
+ printf("done %u bytes\n\r", len);
+ } else {
+ memmove(dst, im, len);
+ }
+
+ flush_cache(dst, len);
+
+ sa = (unsigned long)PROG_START;
+ printf("start address = 0x%x\n\r", sa);
+
+ {
+ struct bi_record *rec;
+
+ rec = (struct bi_record *)_ALIGN((unsigned long)dst+len+(1<<20)-1,(1<<20));
+
+ rec->tag = BI_FIRST;
+ rec->size = sizeof(struct bi_record);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_BOOTLOADER_ID;
+ sprintf( (char *)rec->data, "chrpboot");
+ rec->size = sizeof(struct bi_record) + strlen("chrpboot") + 1;
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_MACHTYPE;
+ rec->data[0] = _MACH_chrp;
+ rec->data[1] = 1;
+ rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+#if 0
+ rec->tag = BI_SYSMAP;
+ rec->data[0] = (unsigned long)sysmap_data;
+ rec->data[1] = sysmap_len;
+ rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+#endif
+ rec->tag = BI_LAST;
+ rec->size = sizeof(struct bi_record);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+ }
+ (*(void (*)())sa)(a1, a2, prom);
+
+ printf("returned?\n\r");
+
+ pause();
+}
+
+void *zalloc(void *x, unsigned items, unsigned size)
+{
+ void *p = avail_ram;
+
+ size *= items;
+ size = (size + 7) & -8;
+ avail_ram += size;
+ if (avail_ram > end_avail) {
+ printf("oops... out of memory\n\r");
+ pause();
+ }
+ return p;
+}
+
+void zfree(void *x, void *addr, unsigned nb)
+{
+ nb = (nb + 7) & -8;
+ if (addr == (avail_ram - nb)) {
+ avail_ram -= nb;
+ }
+}
+
+#define HEAD_CRC 2
+#define EXTRA_FIELD 4
+#define ORIG_NAME 8
+#define COMMENT 0x10
+#define RESERVED 0xe0
+
+#define DEFLATED 8
+
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+ z_stream s;
+ int r, i, flags;
+
+ /* skip header */
+ i = 10;
+ flags = src[3];
+ if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+ printf("bad gzipped data\n\r");
+ exit();
+ }
+ if ((flags & EXTRA_FIELD) != 0)
+ i = 12 + src[10] + (src[11] << 8);
+ if ((flags & ORIG_NAME) != 0)
+ while (src[i++] != 0)
+ ;
+ if ((flags & COMMENT) != 0)
+ while (src[i++] != 0)
+ ;
+ if ((flags & HEAD_CRC) != 0)
+ i += 2;
+ if (i >= *lenp) {
+ printf("gunzip: ran out of data in header\n\r");
+ exit();
+ }
+
+ s.zalloc = zalloc;
+ s.zfree = zfree;
+ r = inflateInit2(&s, -MAX_WBITS);
+ if (r != Z_OK) {
+ printf("inflateInit2 returned %d\n\r", r);
+ exit();
+ }
+ s.next_in = src + i;
+ s.avail_in = *lenp - i;
+ s.next_out = dst;
+ s.avail_out = dstlen;
+ r = inflate(&s, Z_FINISH);
+ if (r != Z_OK && r != Z_STREAM_END) {
+ printf("inflate returned %d msg: %s\n\r", r, s.msg);
+ exit();
+ }
+ *lenp = s.next_out - (unsigned char *) dst;
+ inflateEnd(&s);
+}
--- /dev/null
+/*
+ * BK Id: SCCS/s.misc.S 1.6 05/18/01 15:16:59 cort
+ */
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+ .text
+
+/*
+ * Use the BAT0 registers to map the 1st 8MB of RAM to 0x90000000.
+ */
+ .globl setup_bats
+setup_bats:
+ mfpvr 3
+ rlwinm 3,3,16,16,31 /* r3 = 1 for 601, 4 for 604 */
+ cmpi 0,3,1
+ lis 4,0x9000
+ bne 4f
+ ori 4,4,4 /* set up BAT registers for 601 */
+ li 5,0x7f
+ b 5f
+4: ori 4,4,0xff /* set up BAT registers for 604 */
+ li 5,2
+ mtdbatu 3,4
+ mtdbatl 3,5
+5: mtibatu 3,4
+ mtibatl 3,5
+ isync
+ blr
+
+/*
+ * Flush the dcache and invalidate the icache for a range of addresses.
+ *
+ * flush_cache(addr, len)
+ */
+ .global flush_cache
+flush_cache:
+ addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */
+ rlwinm. 4,4,27,5,31
+ mtctr 4
+ beqlr
+1: dcbf 0,3
+ icbi 0,3
+ addi 3,3,0x20
+ bdnz 1b
+ sync
+ isync
+ blr
--- /dev/null
+/*
+ * BK Id: SCCS/s.start.c 1.6 05/18/01 15:16:59 cort
+ */
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <stdarg.h>
+
+int (*prom)();
+
+void *chosen_handle;
+void *stdin;
+void *stdout;
+void *stderr;
+
+void exit(void);
+void *finddevice(const char *name);
+int getprop(void *phandle, const char *name, void *buf, int buflen);
+
+void printk(char *fmt, ...);
+
+void
+start(int a1, int a2, void *promptr)
+{
+ prom = (int (*)()) promptr;
+ chosen_handle = finddevice("/chosen");
+ if (chosen_handle == (void *) -1)
+ exit();
+ if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
+ exit();
+ stderr = stdout;
+ if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
+ exit();
+
+ chrpboot(a1, a2, promptr);
+ for (;;)
+ exit();
+}
+
+int
+write(void *handle, void *ptr, int nb)
+{
+ struct prom_args {
+ char *service;
+ int nargs;
+ int nret;
+ void *ihandle;
+ void *addr;
+ int len;
+ int actual;
+ } args;
+
+ args.service = "write";
+ args.nargs = 3;
+ args.nret = 1;
+ args.ihandle = handle;
+ args.addr = ptr;
+ args.len = nb;
+ args.actual = -1;
+ (*prom)(&args);
+ return args.actual;
+}
+
+int
+read(void *handle, void *ptr, int nb)
+{
+ struct prom_args {
+ char *service;
+ int nargs;
+ int nret;
+ void *ihandle;
+ void *addr;
+ int len;
+ int actual;
+ } args;
+
+ args.service = "read";
+ args.nargs = 3;
+ args.nret = 1;
+ args.ihandle = handle;
+ args.addr = ptr;
+ args.len = nb;
+ args.actual = -1;
+ (*prom)(&args);
+ return args.actual;
+}
+
+void
+exit()
+{
+ struct prom_args {
+ char *service;
+ } args;
+
+ for (;;) {
+ args.service = "exit";
+ (*prom)(&args);
+ }
+}
+
+void
+pause()
+{
+ struct prom_args {
+ char *service;
+ } args;
+
+ args.service = "enter";
+ (*prom)(&args);
+}
+
+void *
+finddevice(const char *name)
+{
+ struct prom_args {
+ char *service;
+ int nargs;
+ int nret;
+ const char *devspec;
+ void *phandle;
+ } args;
+
+ args.service = "finddevice";
+ args.nargs = 1;
+ args.nret = 1;
+ args.devspec = name;
+ args.phandle = (void *) -1;
+ (*prom)(&args);
+ return args.phandle;
+}
+
+void *
+claim(unsigned int virt, unsigned int size, unsigned int align)
+{
+ struct prom_args {
+ char *service;
+ int nargs;
+ int nret;
+ unsigned int virt;
+ unsigned int size;
+ unsigned int align;
+ void *ret;
+ } args;
+
+ args.service = "claim";
+ args.nargs = 3;
+ args.nret = 1;
+ args.virt = virt;
+ args.size = size;
+ args.align = align;
+ (*prom)(&args);
+ return args.ret;
+}
+
+int
+getprop(void *phandle, const char *name, void *buf, int buflen)
+{
+ struct prom_args {
+ char *service;
+ int nargs;
+ int nret;
+ void *phandle;
+ const char *name;
+ void *buf;
+ int buflen;
+ int size;
+ } args;
+
+ args.service = "getprop";
+ args.nargs = 4;
+ args.nret = 1;
+ args.phandle = phandle;
+ args.name = name;
+ args.buf = buf;
+ args.buflen = buflen;
+ args.size = -1;
+ (*prom)(&args);
+ return args.size;
+}
+
+int
+putc(int c, void *f)
+{
+ char ch = c;
+
+ if (c == '\n')
+ putc('\r', f);
+ return write(f, &ch, 1) == 1? c: -1;
+}
+
+int
+putchar(int c)
+{
+ return putc(c, stdout);
+}
+
+int
+fputs(char *str, void *f)
+{
+ int n = strlen(str);
+
+ return write(f, str, n) == n? 0: -1;
+}
+
+int
+readchar()
+{
+ char ch;
+
+ for (;;) {
+ switch (read(stdin, &ch, 1)) {
+ case 1:
+ return ch;
+ case -1:
+ printk("read(stdin) returned -1\r\n");
+ return -1;
+ }
+ }
+}
+
+static char line[256];
+static char *lineptr;
+static int lineleft;
+
+int
+getchar()
+{
+ int c;
+
+ if (lineleft == 0) {
+ lineptr = line;
+ for (;;) {
+ c = readchar();
+ if (c == -1 || c == 4)
+ break;
+ if (c == '\r' || c == '\n') {
+ *lineptr++ = '\n';
+ putchar('\n');
+ break;
+ }
+ switch (c) {
+ case 0177:
+ case '\b':
+ if (lineptr > line) {
+ putchar('\b');
+ putchar(' ');
+ putchar('\b');
+ --lineptr;
+ }
+ break;
+ case 'U' & 0x1F:
+ while (lineptr > line) {
+ putchar('\b');
+ putchar(' ');
+ putchar('\b');
+ --lineptr;
+ }
+ break;
+ default:
+ if (lineptr >= &line[sizeof(line) - 1])
+ putchar('\a');
+ else {
+ putchar(c);
+ *lineptr++ = c;
+ }
+ }
+ }
+ lineleft = lineptr - line;
+ lineptr = line;
+ }
+ if (lineleft == 0)
+ return -1;
+ --lineleft;
+ return *lineptr++;
+}
+
+extern int vsprintf(char *buf, const char *fmt, va_list args);
+static char sprint_buf[1024];
+
+void
+printk(char *fmt, ...)
+{
+ va_list args;
+ int n;
+
+ va_start(args, fmt);
+ n = vsprintf(sprint_buf, fmt, args);
+ va_end(args);
+ write(stdout, sprint_buf, n);
+}
+
+int
+printf(char *fmt, ...)
+{
+ va_list args;
+ int n;
+
+ va_start(args, fmt);
+ n = vsprintf(sprint_buf, fmt, args);
+ va_end(args);
+ write(stdout, sprint_buf, n);
+ return n;
+}
--- /dev/null
+#
+# arch/ppc/boot/common/Makefile
+#
+# 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.
+#
+# Tom Rini January 2001
+#
+
+.c.s:
+ $(CC) $(CFLAGS) -S -o $*.s $<
+.s.o:
+ $(AS) -o $*.o $<
+.c.o:
+ $(CC) $(CFLAGS) -c -o $*.o $<
+.S.s:
+ $(CPP) $(AFLAGS) -traditional -o $*.o $<
+.S.o:
+ $(CC) $(AFLAGS) -traditional -c -o $*.o $<
+
+OBJCOPY_ARGS = -O elf32-powerpc
+
+coffcrt0.o:
+ $(CC) $(AFLAGS) -DXCOFF -traditional -c -o coffcrt0.o crt0.S
+
+include $(TOPDIR)/Rules.make
--- /dev/null
+/*
+ * BK Id: SCCS/s.crt0.S 1.10 05/21/01 00:49:49 cort
+ */
+/* Copyright (c) 1997 Paul Mackerras <paulus@cs.anu.edu.au>
+ * Initial Power Macintosh COFF version.
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ * Modifications for IBM PowerPC 400-class processor evaluation
+ * boards.
+ *
+ * Module name: crt0.S
+ *
+ * Description:
+ * Boot loader execution entry point. Clears out .bss section as per
+ * ANSI C requirements. Invalidates and flushes the caches over the
+ * range covered by the boot loader's .text section. Sets up a stack
+ * below the .text section entry point.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include "../../kernel/ppc_asm.tmpl"
+
+ .text
+
+ .globl _start
+_start:
+#ifdef XCOFF
+ .long __start,0,0
+
+ .globl __start
+__start:
+#endif
+#ifdef CONFIG_4xx
+ ## Clear out the BSS as per ANSI C requirements
+
+ lis r7,_end@ha
+ addi r7,r7,_end@l # r7 = &_end
+ lis r8,__bss_start@ha #
+ addi r8,r8,__bss_start@l # r8 = &_bss_start
+
+ ## Determine how large an area, in number of words, to clear
+
+ subf r7,r8,r7 # r7 = &_end - &_bss_start + 1
+ addi r7,r7,3 # r7 += 3
+ srwi. r7,r7,2 # r7 = size in words.
+ beq 2f # If the size is zero, do not bother
+ addi r8,r8,-4 # r8 -= 4
+ mtctr r7 # SPRN_CTR = number of words to clear
+ li r0,0 # r0 = 0
+1: stwu r0,4(r8) # Clear out a word
+ bdnz 1b # If we are not done yet, keep clearing
+#endif
+
+ ## Flush and invalidate the caches for the range in memory covering
+ ## the .text section of the boot loader
+
+2: lis r9,_start@h # r9 = &_start
+ lis r8,_etext@ha #
+ addi r8,r8,_etext@l # r8 = &_etext
+3: dcbf r0,r9 # Flush the data cache
+ icbi r0,r9 # Invalidate the instruction cache
+ addi r9,r9,0x10 # Increment by one cache line
+ cmplw cr0,r9,r8 # Are we at the end yet?
+ blt 3b # No, keep flushing and invalidating
+ sync # sync ; isync after flushing the icache
+ isync
+
+#ifdef CONFIG_4xx
+ ## Set up the stack
+
+ lis r9,_start@h # r9 = &_start (text section entry)
+ addi r9,r9,_start@l
+ subi r1,r9,64 # Start the stack 64 bytes below _start
+ clrrwi r1,r1,4 # Make sure it is aligned on 16 bytes.
+ li r0,0
+ stwu r0,-16(r1)
+ mtlr r9
+#endif
+
+ b start # All done, start the real work.
--- /dev/null
+/*
+ * arch/ppc/boot/common/misc-common.c
+ *
+ * Misc. bootloader code (almost) all platforms can use
+ *
+ * Author: Johnnie Peters <jpeters@mvista.com>
+ * Editor: Tom Rini <trini@mvista.com>
+ *
+ * Derived from arch/ppc/boot/prep/misc.c
+ *
+ * Copyright 2000-2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include "zlib.h"
+#include <linux/pci.h>
+
+/* If we're on a ALL_PPC, assume we have a keyboard controller
+ * Also note, if we're not ALL_PPC, we assume you are a serial
+ * console - Tom */
+#ifdef CONFIG_ALL_PPC
+extern void cursor(int x, int y);
+extern void scroll(void);
+extern char *vidmem;
+extern int lines, cols;
+extern int orig_x, orig_y;
+extern int keyb_present;
+extern int CRT_tstc(void);
+extern int CRT_getc(void);
+#else
+int cursor(int x, int y) {return 0;}
+void scroll(void) {}
+char vidmem[1];
+#define lines 0
+#define cols 0
+int orig_x = 0;
+int orig_y = 0;
+#define keyb_present 0
+int CRT_tstc(void) {return 0;}
+int CRT_getc(void) {return 0;}
+#endif
+
+extern char *avail_ram;
+extern char *end_avail;
+extern char _end[];
+
+void puts(const char *);
+void putc(const char c);
+void puthex(unsigned long val);
+void _bcopy(char *src, char *dst, int len);
+void gunzip(void *, int, unsigned char *, int *);
+static int _cvt(unsigned long val, char *buf, long radix, char *digits);
+
+void _vprintk(void(*)(const char), const char *, va_list);
+
+#if defined(CONFIG_SERIAL_CONSOLE)
+struct NS16550 *com_port;
+
+int serial_tstc(volatile struct NS16550 *);
+unsigned char serial_getc(volatile struct NS16550 *);
+void serial_putc(volatile struct NS16550 *, unsigned char);
+#endif
+
+void pause(void)
+{
+ puts("pause\n");
+}
+
+void exit(void)
+{
+ puts("exit\n");
+ while(1);
+}
+
+int tstc(void)
+{
+#if defined(CONFIG_SERIAL_CONSOLE)
+ if(keyb_present)
+ return (CRT_tstc() || serial_tstc(com_port));
+ else
+ return (serial_tstc(com_port));
+#else
+ return CRT_tstc();
+#endif
+}
+
+int getc(void)
+{
+ while (1) {
+#if defined(CONFIG_SERIAL_CONSOLE)
+ if (serial_tstc(com_port))
+ return (serial_getc(com_port));
+#endif /* CONFIG_SERIAL_CONSOLE */
+ if (keyb_present)
+ if(CRT_tstc())
+ return (CRT_getc());
+ }
+}
+
+void
+putc(const char c)
+{
+ int x,y;
+
+#if defined(CONFIG_SERIAL_CONSOLE)
+ serial_putc(com_port, c);
+ if ( c == '\n' )
+ serial_putc(com_port, '\r');
+#endif /* CONFIG_SERIAL_CONSOLE */
+
+ x = orig_x;
+ y = orig_y;
+
+ if ( c == '\n' ) {
+ x = 0;
+ if ( ++y >= lines ) {
+ scroll();
+ y--;
+ }
+ } else if (c == '\r') {
+ x = 0;
+ } else if (c == '\b') {
+ if (x > 0) {
+ x--;
+ }
+ } else {
+ vidmem [ ( x + cols * y ) * 2 ] = c;
+ if ( ++x >= cols ) {
+ x = 0;
+ if ( ++y >= lines ) {
+ scroll();
+ y--;
+ }
+ }
+ }
+
+ cursor(x, y);
+
+ orig_x = x;
+ orig_y = y;
+}
+
+void puts(const char *s)
+{
+ int x,y;
+ char c;
+
+ x = orig_x;
+ y = orig_y;
+
+ while ( ( c = *s++ ) != '\0' ) {
+#if defined(CONFIG_SERIAL_CONSOLE)
+ serial_putc(com_port, c);
+ if ( c == '\n' ) serial_putc(com_port, '\r');
+#endif /* CONFIG_SERIAL_CONSOLE */
+
+ if ( c == '\n' ) {
+ x = 0;
+ if ( ++y >= lines ) {
+ scroll();
+ y--;
+ }
+ } else if (c == '\b') {
+ if (x > 0) {
+ x--;
+ }
+ } else {
+ vidmem [ ( x + cols * y ) * 2 ] = c;
+ if ( ++x >= cols ) {
+ x = 0;
+ if ( ++y >= lines ) {
+ scroll();
+ y--;
+ }
+ }
+ }
+ }
+
+ cursor(x, y);
+
+ orig_x = x;
+ orig_y = y;
+}
+
+void error(char *x)
+{
+ puts("\n\n");
+ puts(x);
+ puts("\n\n -- System halted");
+
+ while(1); /* Halt */
+}
+
+void *zalloc(void *x, unsigned items, unsigned size)
+{
+ void *p = avail_ram;
+
+ size *= items;
+ size = (size + 7) & -8;
+ avail_ram += size;
+ if (avail_ram > end_avail) {
+ puts("oops... out of memory\n");
+ pause();
+ }
+ return p;
+}
+
+void zfree(void *x, void *addr, unsigned nb)
+{
+}
+
+#define HEAD_CRC 2
+#define EXTRA_FIELD 4
+#define ORIG_NAME 8
+#define COMMENT 0x10
+#define RESERVED 0xe0
+
+#define DEFLATED 8
+
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+ z_stream s;
+ int r, i, flags;
+
+ /* skip header */
+ i = 10;
+ flags = src[3];
+ if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+ puts("bad gzipped data\n");
+ exit();
+ }
+ if ((flags & EXTRA_FIELD) != 0)
+ i = 12 + src[10] + (src[11] << 8);
+ if ((flags & ORIG_NAME) != 0)
+ while (src[i++] != 0)
+ ;
+ if ((flags & COMMENT) != 0)
+ while (src[i++] != 0)
+ ;
+ if ((flags & HEAD_CRC) != 0)
+ i += 2;
+ if (i >= *lenp) {
+ puts("gunzip: ran out of data in header\n");
+ exit();
+ }
+
+ s.zalloc = zalloc;
+ s.zfree = zfree;
+ r = inflateInit2(&s, -MAX_WBITS);
+ if (r != Z_OK) {
+ puts("inflateInit2 returned %d\n");
+ exit();
+ }
+ s.next_in = src + i;
+ s.avail_in = *lenp - i;
+ s.next_out = dst;
+ s.avail_out = dstlen;
+ r = inflate(&s, Z_FINISH);
+ if (r != Z_OK && r != Z_STREAM_END) {
+ puts("inflate returned %d\n");
+ exit();
+ }
+ *lenp = s.next_out - (unsigned char *) dst;
+ inflateEnd(&s);
+}
+
+void
+puthex(unsigned long val)
+{
+
+ unsigned char buf[10];
+ int i;
+ for (i = 7; i >= 0; i--)
+ {
+ buf[i] = "0123456789ABCDEF"[val & 0x0F];
+ val >>= 4;
+ }
+ buf[8] = '\0';
+ puts(buf);
+}
+
+#define FALSE 0
+#define TRUE 1
+#include <stdarg.h>
+
+void
+_printk(char const *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ _vprintk(putc, fmt, ap);
+ va_end(ap);
+ return;
+}
+
+#define is_digit(c) ((c >= '0') && (c <= '9'))
+
+void
+_vprintk(void(*putc)(const char), const char *fmt0, va_list ap)
+{
+ char c, sign, *cp = 0;
+ int left_prec, right_prec, zero_fill, length = 0, pad, pad_on_right;
+ char buf[32];
+ long val;
+ while ((c = *fmt0++))
+ {
+ if (c == '%')
+ {
+ c = *fmt0++;
+ left_prec = right_prec = pad_on_right = 0;
+ if (c == '-')
+ {
+ c = *fmt0++;
+ pad_on_right++;
+ }
+ if (c == '0')
+ {
+ zero_fill = TRUE;
+ c = *fmt0++;
+ } else
+ {
+ zero_fill = FALSE;
+ }
+ while (is_digit(c))
+ {
+ left_prec = (left_prec * 10) + (c - '0');
+ c = *fmt0++;
+ }
+ if (c == '.')
+ {
+ c = *fmt0++;
+ zero_fill++;
+ while (is_digit(c))
+ {
+ right_prec = (right_prec * 10) + (c - '0');
+ c = *fmt0++;
+ }
+ } else
+ {
+ right_prec = left_prec;
+ }
+ sign = '\0';
+ switch (c)
+ {
+ case 'd':
+ case 'x':
+ case 'X':
+ val = va_arg(ap, long);
+ switch (c)
+ {
+ case 'd':
+ if (val < 0)
+ {
+ sign = '-';
+ val = -val;
+ }
+ length = _cvt(val, buf, 10, "0123456789");
+ break;
+ case 'x':
+ length = _cvt(val, buf, 16, "0123456789abcdef");
+ break;
+ case 'X':
+ length = _cvt(val, buf, 16, "0123456789ABCDEF");
+ break;
+ }
+ cp = buf;
+ break;
+ case 's':
+ cp = va_arg(ap, char *);
+ length = strlen(cp);
+ break;
+ case 'c':
+ c = va_arg(ap, long /*char*/);
+ (*putc)(c);
+ continue;
+ default:
+ (*putc)('?');
+ }
+ pad = left_prec - length;
+ if (sign != '\0')
+ {
+ pad--;
+ }
+ if (zero_fill)
+ {
+ c = '0';
+ if (sign != '\0')
+ {
+ (*putc)(sign);
+ sign = '\0';
+ }
+ } else
+ {
+ c = ' ';
+ }
+ if (!pad_on_right)
+ {
+ while (pad-- > 0)
+ {
+ (*putc)(c);
+ }
+ }
+ if (sign != '\0')
+ {
+ (*putc)(sign);
+ }
+ while (length-- > 0)
+ {
+ (*putc)(c = *cp++);
+ if (c == '\n')
+ {
+ (*putc)('\r');
+ }
+ }
+ if (pad_on_right)
+ {
+ while (pad-- > 0)
+ {
+ (*putc)(c);
+ }
+ }
+ } else
+ {
+ (*putc)(c);
+ if (c == '\n')
+ {
+ (*putc)('\r');
+ }
+ }
+ }
+}
+
+int
+_cvt(unsigned long val, char *buf, long radix, char *digits)
+{
+ char temp[80];
+ char *cp = temp;
+ int length = 0;
+ if (val == 0)
+ { /* Special case */
+ *cp++ = '0';
+ } else
+ while (val)
+ {
+ *cp++ = digits[val % radix];
+ val /= radix;
+ }
+ while (cp != temp)
+ {
+ *buf++ = *--cp;
+ length++;
+ }
+ *buf = '\0';
+ return (length);
+}
+
+void
+_dump_buf_with_offset(unsigned char *p, int s, unsigned char *base)
+{
+ int i, c;
+ if ((unsigned int)s > (unsigned int)p)
+ {
+ s = (unsigned int)s - (unsigned int)p;
+ }
+ while (s > 0)
+ {
+ if (base)
+ {
+ _printk("%06X: ", (int)p - (int)base);
+ } else
+ {
+ _printk("%06X: ", p);
+ }
+ for (i = 0; i < 16; i++)
+ {
+ if (i < s)
+ {
+ _printk("%02X", p[i] & 0xFF);
+ } else
+ {
+ _printk(" ");
+ }
+ if ((i % 2) == 1) _printk(" ");
+ if ((i % 8) == 7) _printk(" ");
+ }
+ _printk(" |");
+ for (i = 0; i < 16; i++)
+ {
+ if (i < s)
+ {
+ c = p[i] & 0xFF;
+ if ((c < 0x20) || (c >= 0x7F)) c = '.';
+ } else
+ {
+ c = ' ';
+ }
+ _printk("%c", c);
+ }
+ _printk("|\n");
+ s -= 16;
+ p += 16;
+ }
+}
+
+void
+_dump_buf(unsigned char *p, int s)
+{
+ _printk("\n");
+ _dump_buf_with_offset(p, s, 0);
+}
+
+/*
+ * Local variables:
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
--- /dev/null
+/*
+ * arch/ppc/common/misc-simple.c
+ *
+ * Misc. bootloader code for many machines. This assumes you have are using
+ * a 6xx/7xx/74xx CPU in your machine. This assumes the chunk of memory
+ * below 8MB is free. Finally, it assumes you have a NS16550-style uart for
+ * your serial console. If a machine meets these requirements, it can quite
+ * likely use this code during boot.
+ *
+ * Author: Matt Porter <mporter@mvista.com>
+ * Derived from arch/ppc/boot/prep/misc.c
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/types.h>
+#include <linux/elf.h>
+#include <linux/config.h>
+
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/mmu.h>
+
+#include "zlib.h"
+
+unsigned long com_port;
+
+char *avail_ram;
+char *end_avail;
+extern char _end[];
+
+#ifdef CONFIG_CMDLINE
+#define CMDLINE CONFIG_CMDLINE
+#else
+#define CMDLINE ""
+#endif
+char cmd_preset[] = CMDLINE;
+char cmd_buf[256];
+char *cmd_line = cmd_buf;
+
+unsigned long initrd_start = 0, initrd_end = 0;
+char *zimage_start;
+int zimage_size;
+
+extern void puts(const char *);
+extern void putc(const char c);
+extern void puthex(unsigned long val);
+extern void *memcpy(void * __dest, __const void * __src,
+ __kernel_size_t __n);
+extern void gunzip(void *, int, unsigned char *, int *);
+extern void udelay(long delay);
+extern int tstc(void);
+extern int getc(void);
+extern volatile unsigned long serial_init(int chan);
+
+void
+decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
+{
+
+ int timer = 0;
+ extern unsigned long start;
+ char *cp, ch;
+
+ com_port = serial_init(0);
+
+ /* assume the chunk below 8M is free */
+ end_avail = (char *)0x00800000;
+
+ /*
+ * Reveal where we were loaded at and where we
+ * were relocated to.
+ */
+ puts("loaded at: "); puthex(load_addr);
+ puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n");
+ if ( (unsigned long)load_addr != (unsigned long)&start )
+ {
+ puts("relocated to: "); puthex((unsigned long)&start);
+ puts(" ");
+ puthex((unsigned long)((unsigned long)&start + (4*num_words)));
+ puts("\n");
+ }
+
+ /* we have to subtract 0x10000 here to correct for objdump including
+ the size of the elf header which we strip -- Cort */
+ zimage_start = (char *)(load_addr - 0x10000 + ZIMAGE_OFFSET);
+ zimage_size = ZIMAGE_SIZE;
+
+ if ( INITRD_OFFSET )
+ initrd_start = load_addr - 0x10000 + INITRD_OFFSET;
+ else
+ initrd_start = 0;
+ initrd_end = INITRD_SIZE + initrd_start;
+
+ /*
+ * Find a place to stick the zimage and initrd and
+ * relocate them if we have to. -- Cort
+ */
+ avail_ram = (char *)PAGE_ALIGN((unsigned long)_end);
+ puts("zimage at: "); puthex((unsigned long)zimage_start);
+ puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); puts("\n");
+ if ( (unsigned long)zimage_start <= 0x00800000 )
+ {
+ memcpy( (void *)avail_ram, (void *)zimage_start, zimage_size );
+ zimage_start = (char *)avail_ram;
+ puts("relocated to: "); puthex((unsigned long)zimage_start);
+ puts(" ");
+ puthex((unsigned long)zimage_size+(unsigned long)zimage_start);
+ puts("\n");
+
+ /* relocate initrd */
+ if ( initrd_start )
+ {
+ puts("initrd at: "); puthex(initrd_start);
+ puts(" "); puthex(initrd_end); puts("\n");
+ avail_ram = (char *)PAGE_ALIGN(
+ (unsigned long)zimage_size+(unsigned long)zimage_start);
+ memcpy ((void *)avail_ram, (void *)initrd_start, INITRD_SIZE );
+ initrd_start = (unsigned long)avail_ram;
+ initrd_end = initrd_start + INITRD_SIZE;
+ puts("relocated to: "); puthex(initrd_start);
+ puts(" "); puthex(initrd_end); puts("\n");
+ }
+ } else if ( initrd_start ) {
+ puts("initrd at: "); puthex(initrd_start);
+ puts(" "); puthex(initrd_end); puts("\n");
+ }
+
+ avail_ram = (char *)0x00400000;
+ end_avail = (char *)0x00800000;
+ puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" ");
+ puthex((unsigned long)end_avail); puts("\n");
+
+ /* Display standard Linux/PPC boot prompt for kernel args */
+ puts("\nLinux/PPC load: ");
+ cp = cmd_line;
+ memcpy (cmd_line, cmd_preset, sizeof(cmd_preset));
+ while ( *cp ) putc(*cp++);
+ while (timer++ < 5*1000) {
+ if (tstc()) {
+ while ((ch = getc()) != '\n' && ch != '\r') {
+ /* Test for backspace/delete */
+ if (ch == '\b' || ch == '\177') {
+ if (cp != cmd_line) {
+ cp--;
+ puts("\b \b");
+ }
+ /* Test for ^x/^u (and wipe the line) */
+ } else if (ch == '\030' || ch == '\025') {
+ while (cp != cmd_line) {
+ cp--;
+ puts("\b \b");
+ }
+ } else {
+ *cp++ = ch;
+ putc(ch);
+ }
+ }
+ break; /* Exit 'timer' loop */
+ }
+ udelay(1000); /* 1 msec */
+ }
+ *cp = 0;
+ puts("\n");
+
+ /* mappings on early boot can only handle 16M */
+ if ( (int)(cmd_line[0]) > (16<<20))
+ puts("cmd_line located > 16M\n");
+ if ( initrd_start > (16<<20))
+ puts("initrd_start located > 16M\n");
+
+ puts("Uncompressing Linux...");
+
+ gunzip(0, 0x400000, zimage_start, &zimage_size);
+ puts("done.\n");
+
+ puts("Now booting the kernel\n");
+}
--- /dev/null
+/*
+ * BK Id: SCCS/s.no_initrd.c 1.7 05/18/01 15:17:23 cort
+ */
+char initrd_data[1];
+int initrd_len = 0;
--- /dev/null
+/*
+ * BK Id: SCCS/s.ns16550.c 1.7 05/18/01 06:20:29 patch
+ */
+/*
+ * COM1 NS16550 support
+ */
+
+#include <linux/config.h>
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+#include <asm/serial.h>
+
+/* Some machines, such as ones with a PReP memory map, initally have
+ * their serial port at an offset of 0x80000000 from where they are
+ * in <asm/serial.h>. This tries to take that into account. */
+#ifndef IOOFFSET
+#define IOOFFSET 0
+#endif
+
+static struct serial_state rs_table[RS_TABLE_SIZE] = {
+ SERIAL_PORT_DFNS /* Defined in <asm/serial.h> */
+};
+
+static int shift;
+
+volatile unsigned long serial_init(int chan) {
+ unsigned long com_port;
+
+ /* Get the base, and add any offset we need to deal with. */
+ com_port = rs_table[chan].port + IOOFFSET;
+
+ /* How far apart the registers are. */
+ shift = rs_table[chan].iomem_reg_shift;
+
+ /* See if port is present */
+ *((unsigned char *)com_port + (UART_LCR << shift)) = 0x00;
+ *((unsigned char *)com_port + (UART_IER << shift)) = 0x00;
+ /* Access baud rate */
+ *((unsigned char *)com_port + (UART_LCR << shift)) = 0x00;
+#ifdef CONFIG_SERIAL_CONSOLE_NONSTD
+ /* Input clock. */
+ *((unsigned char *)com_port + (UART_DLL << shift)) =
+ (BASE_BAUD / CONFIG_SERIAL_CONSOLE_BAUD);
+ *((unsigned char *)com_port + (UART_DLM << shift)) =
+ (BASE_BAUD / CONFIG_SERIAL_CONSOLE_BAUD) >> 8;
+#endif
+ /* 8 data, 1 stop, no parity */
+ *((unsigned char *)com_port + (UART_LCR << shift)) = 0x03;
+ /* RTS/DTR */
+ *((unsigned char *)com_port + (UART_MCR << shift)) = 0x03;
+ /* Clear & enable FIFOs */
+ *((unsigned char *)com_port + (UART_FCR << shift)) = 0x07;
+
+ return (com_port);
+}
+
+void
+serial_putc(volatile unsigned long com_port, unsigned char c)
+{
+ while ((*((volatile unsigned char *)com_port + (UART_LSR << shift)) &
+ UART_LSR_THRE) == 0)
+ ;
+ *(volatile unsigned char *)com_port = c;
+}
+
+unsigned char
+serial_getc(volatile unsigned long com_port)
+{
+ while ((*((volatile unsigned char *)com_port + (UART_LSR << shift))
+ & UART_LSR_DR) == 0)
+ ;
+ return (*(volatile unsigned char *)com_port);
+}
+
+int
+serial_tstc(volatile unsigned long com_port)
+{
+ return ((*((volatile unsigned char *)com_port + (UART_LSR << shift))
+ & UART_LSR_DR) != 0);
+}
--- /dev/null
+/*
+ * BK Id: SCCS/s.string.S 1.8 05/18/01 06:20:29 patch
+ */
+/*
+ * String handling functions for PowerPC.
+ *
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#define r0 0
+#define r3 3
+#define r4 4
+#define r5 5
+#define r6 6
+#define r7 7
+#define r8 8
+
+ .globl strlen
+strlen:
+ addi r4,r3,-1
+1: lbzu r0,1(r4)
+ cmpwi 0,r0,0
+ bne 1b
+ subf r3,r3,r4
+ blr
+
+ .globl memset
+memset:
+ rlwimi r4,r4,8,16,23
+ rlwimi r4,r4,16,0,15
+ addi r6,r3,-4
+ cmplwi 0,r5,4
+ blt 7f
+ stwu r4,4(r6)
+ beqlr
+ andi. r0,r6,3
+ add r5,r0,r5
+ subf r6,r0,r6
+ rlwinm r0,r5,32-2,2,31
+ mtctr r0
+ bdz 6f
+1: stwu r4,4(r6)
+ bdnz 1b
+6: andi. r5,r5,3
+7: cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+ addi r6,r6,3
+8: stbu r4,1(r6)
+ bdnz 8b
+ blr
+
+ .globl memmove
+memmove:
+ cmplw 0,r3,r4
+ bgt backwards_memcpy
+ /* fall through */
+
+ .globl memcpy
+memcpy:
+ rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
+ addi r6,r3,-4
+ addi r4,r4,-4
+ beq 2f /* if less than 8 bytes to do */
+ andi. r0,r6,3 /* get dest word aligned */
+ mtctr r7
+ bne 5f
+1: lwz r7,4(r4)
+ lwzu r8,8(r4)
+ stw r7,4(r6)
+ stwu r8,8(r6)
+ bdnz 1b
+ andi. r5,r5,7
+2: cmplwi 0,r5,4
+ blt 3f
+ lwzu r0,4(r4)
+ addi r5,r5,-4
+ stwu r0,4(r6)
+3: cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+ addi r4,r4,3
+ addi r6,r6,3
+4: lbzu r0,1(r4)
+ stbu r0,1(r6)
+ bdnz 4b
+ blr
+5: subfic r0,r0,4
+ mtctr r0
+6: lbz r7,4(r4)
+ addi r4,r4,1
+ stb r7,4(r6)
+ addi r6,r6,1
+ bdnz 6b
+ subf r5,r0,r5
+ rlwinm. r7,r5,32-3,3,31
+ beq 2b
+ mtctr r7
+ b 1b
+
+ .globl backwards_memcpy
+backwards_memcpy:
+ rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
+ add r6,r3,r5
+ add r4,r4,r5
+ beq 2f
+ andi. r0,r6,3
+ mtctr r7
+ bne 5f
+1: lwz r7,-4(r4)
+ lwzu r8,-8(r4)
+ stw r7,-4(r6)
+ stwu r8,-8(r6)
+ bdnz 1b
+ andi. r5,r5,7
+2: cmplwi 0,r5,4
+ blt 3f
+ lwzu r0,-4(r4)
+ subi r5,r5,4
+ stwu r0,-4(r6)
+3: cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+4: lbzu r0,-1(r4)
+ stbu r0,-1(r6)
+ bdnz 4b
+ blr
+5: mtctr r0
+6: lbzu r7,-1(r4)
+ stbu r7,-1(r6)
+ bdnz 6b
+ subf r5,r0,r5
+ rlwinm. r7,r5,32-3,3,31
+ beq 2b
+ mtctr r7
+ b 1b
+
+ .globl memcmp
+memcmp:
+ cmpwi 0,r5,0
+ blelr
+ mtctr r5
+ addi r6,r3,-1
+ addi r4,r4,-1
+1: lbzu r3,1(r6)
+ lbzu r0,1(r4)
+ subf. r3,r0,r3
+ bdnzt 2,1b
+ blr
+++ /dev/null
-#include "../kernel/ppc_defs.h"
-#include "../kernel/ppc_asm.tmpl"
-#include <asm/processor.h>
-#include <asm/cache.h>
-
- .text
-
-/*
- * $Id: head.S,v 1.33 1999/09/08 01:06:58 cort Exp $
- *
- * Boot loader philosophy:
- * ROM loads us to some arbitrary location
- * Move the boot code to the link address (8M)
- * Call decompress_kernel()
- * Relocate the initrd, zimage and residual data to 8M
- * Decompress the kernel to 0
- * Jump to the kernel entry
- * -- Cort
- */
- .globl start
-start:
- bl start_
-start_:
- mr r11,r3 /* Save pointer to residual/board data */
- mr r25,r5 /* Save OFW pointer */
- li r3,MSR_IP /* Establish default MSR value */
- mtmsr r3
-
-/* check if we need to relocate ourselves to the link addr or were we
- loaded there to begin with -- Cort */
- lis r4,start@h
- ori r4,r4,start@l
- mflr r3
- subi r3,r3,4 /* we get the nip, not the ip of the branch */
- mr r8,r3
- cmp 0,r3,r4
- bne 1010f
-/* compute size of whole image in words. this should be moved to
- * start_ldr() -- Cort
- */
- lis r4,start@h
- ori r4,r4,start@l
- lis r5,end@h
- ori r5,r5,end@l
- addi r5,r5,3 /* round up */
- sub r5,r5,r4
- srwi r5,r5,2
- mr r7,r5
- b start_ldr
-1010:
-/*
- * no matter where we're loaded, move ourselves to -Ttext address
- */
-relocate:
- mflr r3 /* Compute code bias */
- subi r3,r3,4
- mr r8,r3
- lis r4,start@h
- ori r4,r4,start@l
- lis r5,end@h
- ori r5,r5,end@l
- addi r5,r5,3 /* Round up - just in case */
- sub r5,r5,r4 /* Compute # longwords to move */
- srwi r5,r5,2
- mtctr r5
- mr r7,r5
- li r6,0
- subi r3,r3,4 /* Set up for loop */
- subi r4,r4,4
-00: lwzu r5,4(r3)
- stwu r5,4(r4)
- xor r6,r6,r5
- bdnz 00b
- lis r3,start_ldr@h
- ori r3,r3,start_ldr@l
- mtlr r3 /* Easiest way to do an absolute jump */
- blr
-start_ldr:
-/* Clear all of BSS */
- lis r3,edata@h
- ori r3,r3,edata@l
- lis r4,end@h
- ori r4,r4,end@l
- subi r3,r3,4
- subi r4,r4,4
- li r0,0
-50: stwu r0,4(r3)
- cmp 0,r3,r4
- bne 50b
-90: mr r9,r1 /* Save old stack pointer (in case it matters) */
- lis r1,.stack@h
- ori r1,r1,.stack@l
- addi r1,r1,4096*2
- subi r1,r1,256
- li r2,0x000F /* Mask pointer to 16-byte boundary */
- andc r1,r1,r2
-/* Run loader */
- mr r3,r8 /* Load point */
- mr r4,r7 /* Program length */
- mr r5,r6 /* Checksum */
- mr r6,r11 /* Residual data */
- mr r7,r25 /* OFW interfaces */
- bl decompress_kernel
-
- /* changed to use r3 (as firmware does) for kernel
- as ptr to residual -- Cort*/
- lis r6,cmd_line@h
- ori r6,r6,cmd_line@l
- lwz r6, 0(r6)
- subi r7,r6,1
-00: lbzu r2,1(r7)
- cmpi 0,r2,0
- bne 00b
-
- /* tell kernel we're prep */
- /*
- * get start address of kernel code which is stored as a coff
- * entry. see boot/head.S -- Cort
- */
- li r9,0x4
- mtlr r9
- lis r10,0xdeadc0de@h
- ori r10,r10,0xdeadc0de@l
- li r9,0
- stw r10,0(r9)
-/*
- * The Radstone firmware maps PCI memory at 0xc0000000 using BAT2
- * so disable BATs before setting this to avoid a clash
- */
- li r8,0
- mtspr DBAT0U,r8
- mtspr DBAT1U,r8
- mtspr DBAT2U,r8
- mtspr DBAT3U,r8
- mtspr IBAT0U,r8
- mtspr IBAT1U,r8
- mtspr IBAT2U,r8
- mtspr IBAT3U,r8
-
- blr
-hang:
- b hang
-
-/*
- * Delay for a number of microseconds
- * -- Use the BUS timer (assumes 66MHz)
- */
- .globl udelay
-udelay:
- mfspr r4,PVR
- srwi r4,r4,16
- cmpi 0,r4,1 /* 601 ? */
- bne .udelay_not_601
-00: li r0,86 /* Instructions / microsecond? */
- mtctr r0
-10: addi r0,r0,0 /* NOP */
- bdnz 10b
- subic. r3,r3,1
- bne 00b
- blr
-
-.udelay_not_601:
- mulli r4,r3,1000 /* nanoseconds */
- addi r4,r4,59
- li r5,60
- divw r4,r4,r5 /* BUS ticks */
-1: mftbu r5
- mftb r6
- mftbu r7
- cmp 0,r5,r7
- bne 1b /* Get [synced] base time */
- addc r9,r6,r4 /* Compute end time */
- addze r8,r5
-2: mftbu r5
- cmp 0,r5,r8
- blt 2b
- bgt 3f
- mftb r6
- cmp 0,r6,r9
- blt 2b
-3: blr
-
-.globl _get_HID0
-_get_HID0:
- mfspr r3,HID0
- blr
-
-.globl _put_HID0
-_put_HID0:
- mtspr HID0,r3
- blr
-
-.globl _get_MSR
-_get_MSR:
- mfmsr r3
- blr
-
-.globl _put_MSR
-_put_MSR:
- mtmsr r3
- blr
-
-/*
- * Flush instruction cache
- * *** I'm really paranoid here!
- */
-_GLOBAL(flush_instruction_cache)
- mflr r5
- bl flush_data_cache
- mfspr r3,HID0 /* Caches are controlled by this register */
- li r4,0
- ori r4,r4,(HID0_ICE|HID0_ICFI)
- or r3,r3,r4 /* Need to enable+invalidate to clear */
- mtspr HID0,r3
- andc r3,r3,r4
- ori r3,r3,HID0_ICE /* Enable cache */
- mtspr HID0,r3
- mtlr r5
- blr
-
-#define NUM_CACHE_LINES 128*8
-#define CACHE_LINE_SIZE 32
-#define cache_flush_buffer 0x1000
-
-/*
- * Flush data cache
- * *** I'm really paranoid here!
- */
-_GLOBAL(flush_data_cache)
- lis r3,cache_flush_buffer@h
- ori r3,r3,cache_flush_buffer@l
- li r4,NUM_CACHE_LINES
- mtctr r4
-00: lwz r4,0(r3)
- addi r3,r3,CACHE_LINE_SIZE /* Next line, please */
- bdnz 00b
-10: blr
- .comm .stack,4096*2,4
--- /dev/null
+#
+# This dir holds all of the images for PPC machines.
+# Tom Rini January 2001
+
+include $(TOPDIR)/Rules.make
+
+vmlinux.gz: $(TOPDIR)/vmlinux
+ $(OBJCOPY) -S -O binary $(TOPDIR)/vmlinux vmlinux
+ gzip -vf9 vmlinux
+
+clean:
+ rm -f sImage vmapus vmlinux.* miboot.image* zImage* zvmlinux.*
--- /dev/null
+/*
+ * BK Id: SCCS/s.nonstdio.h 1.7 05/18/01 15:17:23 cort
+ */
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+typedef int FILE;
+extern FILE *stdin, *stdout;
+#define NULL ((void *)0)
+#define EOF (-1)
+#define fopen(n, m) NULL
+#define fflush(f) 0
+#define fclose(f) 0
+extern char *fgets();
+
+#define perror(s) printf("%s: no files!\n", (s))
--- /dev/null
+/*
+ * BK Id: SCCS/s.rs6000.h 1.7 05/18/01 15:17:23 cort
+ */
+/* IBM RS/6000 "XCOFF" file definitions for BFD.
+ Copyright (C) 1990, 1991 Free Software Foundation, Inc.
+ FIXME: Can someone provide a transliteration of this name into ASCII?
+ Using the following chars caused a compiler warning on HIUX (so I replaced
+ them with octal escapes), and isn't useful without an understanding of what
+ character set it is.
+ Written by Mimi Ph\373\364ng-Th\345o V\365 of IBM
+ and John Gilmore of Cygnus Support. */
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+ /* IBM RS/6000 */
+#define U802WRMAGIC 0730 /* writeable text segments **chh** */
+#define U802ROMAGIC 0735 /* readonly sharable text segments */
+#define U802TOCMAGIC 0737 /* readonly text segments and TOC */
+
+#define BADMAG(x) \
+ ((x).f_magic != U802ROMAGIC && (x).f_magic != U802WRMAGIC && \
+ (x).f_magic != U802TOCMAGIC)
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+typedef struct
+{
+ unsigned char magic[2]; /* type of file */
+ unsigned char vstamp[2]; /* version stamp */
+ unsigned char tsize[4]; /* text size in bytes, padded to FW bdry */
+ unsigned char dsize[4]; /* initialized data " " */
+ unsigned char bsize[4]; /* uninitialized data " " */
+ unsigned char entry[4]; /* entry pt. */
+ unsigned char text_start[4]; /* base of text used for this file */
+ unsigned char data_start[4]; /* base of data used for this file */
+ unsigned char o_toc[4]; /* address of TOC */
+ unsigned char o_snentry[2]; /* section number of entry point */
+ unsigned char o_sntext[2]; /* section number of .text section */
+ unsigned char o_sndata[2]; /* section number of .data section */
+ unsigned char o_sntoc[2]; /* section number of TOC */
+ unsigned char o_snloader[2]; /* section number of .loader section */
+ unsigned char o_snbss[2]; /* section number of .bss section */
+ unsigned char o_algntext[2]; /* .text alignment */
+ unsigned char o_algndata[2]; /* .data alignment */
+ unsigned char o_modtype[2]; /* module type (??) */
+ unsigned char o_cputype[2]; /* cpu type */
+ unsigned char o_maxstack[4]; /* max stack size (??) */
+ unsigned char o_maxdata[4]; /* max data size (??) */
+ unsigned char o_resv2[12]; /* reserved */
+}
+AOUTHDR;
+
+#define AOUTSZ 72
+#define SMALL_AOUTSZ (28)
+#define AOUTHDRSZ 72
+
+#define RS6K_AOUTHDR_OMAGIC 0x0107 /* old: text & data writeable */
+#define RS6K_AOUTHDR_NMAGIC 0x0108 /* new: text r/o, data r/w */
+#define RS6K_AOUTHDR_ZMAGIC 0x010B /* paged: text r/o, both page-aligned */
+
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr {
+ char s_name[8]; /* section name */
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[2]; /* number of relocation entries */
+ char s_nlnno[2]; /* number of line number entries*/
+ char s_flags[4]; /* flags */
+};
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+#define _PAD ".pad"
+#define _LOADER ".loader"
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+/* XCOFF uses a special .loader section with type STYP_LOADER. */
+#define STYP_LOADER 0x1000
+
+/* XCOFF uses a special .debug section with type STYP_DEBUG. */
+#define STYP_DEBUG 0x2000
+
+/* XCOFF handles line number or relocation overflow by creating
+ another section header with STYP_OVRFLO set. */
+#define STYP_OVRFLO 0x8000
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+ union {
+ char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+ char l_lnno[2]; /* line number */
+};
+
+
+#define LINENO struct external_lineno
+#define LINESZ 6
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN 8 /* # characters in a symbol name */
+#define E_FILNMLEN 14 /* # characters in a file name */
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ char e_zeroes[4];
+ char e_offset[4];
+ } e;
+ } e;
+ char e_value[4];
+ char e_scnum[2];
+ char e_type[2];
+ char e_sclass[1];
+ char e_numaux[1];
+};
+
+
+
+#define N_BTMASK (017)
+#define N_TMASK (060)
+#define N_BTSHFT (4)
+#define N_TSHIFT (2)
+
+
+union external_auxent {
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ union {
+ struct {
+ char x_lnno[2]; /* declaration line number */
+ char x_size[2]; /* str/union/array size */
+ } x_lnsz;
+ char x_fsize[4]; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ char x_tvndx[2]; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[2]; /* # relocation entries */
+ char x_nlinno[2]; /* # line numbers */
+ } x_scn;
+
+ struct {
+ char x_tvfill[4]; /* tv fill value */
+ char x_tvlen[2]; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+
+ struct {
+ unsigned char x_scnlen[4];
+ unsigned char x_parmhash[4];
+ unsigned char x_snhash[2];
+ unsigned char x_smtyp[1];
+ unsigned char x_smclas[1];
+ unsigned char x_stab[4];
+ unsigned char x_snstab[2];
+ } x_csect;
+
+};
+
+#define SYMENT struct external_syment
+#define SYMESZ 18
+#define AUXENT union external_auxent
+#define AUXESZ 18
+#define DBXMASK 0x80 /* for dbx storage mask */
+#define SYMNAME_IN_DEBUG(symptr) ((symptr)->n_sclass & DBXMASK)
+
+
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+
+struct external_reloc {
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_size[1];
+ char r_type[1];
+};
+
+
+#define RELOC struct external_reloc
+#define RELSZ 10
+
+#define DEFAULT_DATA_SECTION_ALIGNMENT 4
+#define DEFAULT_BSS_SECTION_ALIGNMENT 4
+#define DEFAULT_TEXT_SECTION_ALIGNMENT 4
+/* For new sections we havn't heard of before */
+#define DEFAULT_SECTION_ALIGNMENT 4
--- /dev/null
+/*
+ * BK Id: SCCS/s.zlib.h 1.8 05/18/01 15:17:23 cort
+ */
+/*
+ * This file is derived from zlib.h and zconf.h from the zlib-0.95
+ * distribution by Jean-loup Gailly and Mark Adler, with some additions
+ * by Paul Mackerras to aid in implementing Deflate compression and
+ * decompression for PPP packets.
+ */
+
+/*
+ * ==FILEVERSION 960122==
+ *
+ * This marker is used by the Linux installation script to determine
+ * whether an up-to-date version of this file is already installed.
+ */
+
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 0.95, Aug 16th, 1995.
+
+ Copyright (C) 1995 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ gzip@prep.ai.mit.edu madler@alumni.caltech.edu
+ */
+
+#ifndef _ZLIB_H
+#define _ZLIB_H
+
+/* #include "zconf.h" */ /* included directly here */
+
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */
+
+/*
+ The library does not install any signal handler. It is recommended to
+ add at least a handler for SIGSEGV when decompressing; the library checks
+ the consistency of the input data whenever possible but may go nuts
+ for some forms of corrupted input.
+ */
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints
+ * at addresses which are not a multiple of their size.
+ * Under DOS, -DFAR=far or -DFAR=__far may be needed.
+ */
+
+#ifndef STDC
+# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus)
+# define STDC
+# endif
+#endif
+
+#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */
+# include <unix.h>
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2 */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ 1 << (windowBits+2) + 1 << (memLevel+9)
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+typedef unsigned char Byte; /* 8 bits */
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+typedef Byte FAR Bytef;
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+/* end of original zconf.h */
+
+#define ZLIB_VERSION "0.95P"
+
+/*
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed
+ data. This version of the library supports only one compression method
+ (deflation) but other algorithms may be added later and will have the same
+ stream interface.
+
+ For compression the application must provide the output buffer and
+ may optionally provide the input buffer for optimization. For decompression,
+ the application must provide the input buffer and may optionally provide
+ the output buffer for optimization.
+
+ Compression can be done in a single step if the buffers are large
+ enough (for example if an input file is mmap'ed), or can be done by
+ repeated calls of the compression function. In the latter case, the
+ application must provide more input and/or consume the output
+ (providing more output space) before each call.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+ Bytef *next_in; /* next input byte */
+ uInt avail_in; /* number of bytes available at next_in */
+ uLong total_in; /* total nb of input bytes read so far */
+
+ Bytef *next_out; /* next output byte should be put there */
+ uInt avail_out; /* remaining free space at next_out */
+ uLong total_out; /* total nb of bytes output so far */
+
+ char *msg; /* last error message, NULL if no error */
+ struct internal_state FAR *state; /* not visible by applications */
+
+ alloc_func zalloc; /* used to allocate the internal state */
+ free_func zfree; /* used to free the internal state */
+ voidp opaque; /* private data object passed to zalloc and zfree */
+
+ Byte data_type; /* best guess about the data type: ascii or binary */
+
+} z_stream;
+
+/*
+ The application must update next_in and avail_in when avail_in has
+ dropped to zero. It must update next_out and avail_out when avail_out
+ has dropped to zero. The application must initialize zalloc, zfree and
+ opaque before calling the init function. All other fields are set by the
+ compression library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
+ opaque value.
+
+ zalloc must return Z_NULL if there is not enough memory for the object.
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this
+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
+ have their offset normalized to zero. The default allocation function
+ provided by this library ensures this (see zutil.c). To reduce memory
+ requirements and avoid any allocation of 64K objects, at the expense of
+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or
+ progress reports. After compression, total_in holds the total size of
+ the uncompressed data and may be saved for use in the decompressor
+ (particularly if the decompressor wants to decompress everything in
+ a single step).
+*/
+
+ /* constants */
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1
+#define Z_FULL_FLUSH 2
+#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */
+#define Z_FINISH 4
+#define Z_PACKET_FLUSH 5
+/* See deflate() below for the usage of these constants */
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+/* error codes for the compression/decompression functions */
+
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+/* compression levels */
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_DEFAULT_STRATEGY 0
+
+#define Z_BINARY 0
+#define Z_ASCII 1
+#define Z_UNKNOWN 2
+/* Used to set the data_type field */
+
+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
+
+extern char *zlib_version;
+/* The application can compare zlib_version and ZLIB_VERSION for consistency.
+ If the first character differs, the library code actually used is
+ not compatible with the zlib.h header file used by the application.
+ */
+
+ /* basic functions */
+
+extern int inflateInit OF((z_stream *strm));
+/*
+ Initializes the internal stream state for decompression. The fields
+ zalloc and zfree must be initialized before by the caller. If zalloc and
+ zfree are set to Z_NULL, inflateInit updates them to use default allocation
+ functions.
+
+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory. msg is set to null if there is no error message.
+ inflateInit does not perform any decompression: this will be done by
+ inflate().
+*/
+
+
+extern int inflate OF((z_stream *strm, int flush));
+/*
+ Performs one or both of the following actions:
+
+ - Decompress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in is updated and processing
+ will resume at this point for the next call of inflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. inflate() always provides as much output as possible
+ (until there is no more input data or no more space in the output buffer).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming
+ more output, and updating the next_* and avail_* values accordingly.
+ The application can consume the uncompressed output when it wants, for
+ example when the output buffer is full (avail_out == 0), or after each
+ call of inflate().
+
+ If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH,
+ inflate flushes as much output as possible to the output buffer. The
+ flushing behavior of inflate is not specified for values of the flush
+ parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the
+ current implementation actually flushes as much output as possible
+ anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data
+ has been consumed, it is expecting to see the length field of a stored
+ block; if not, it returns Z_DATA_ERROR.
+
+ inflate() should normally be called until it returns Z_STREAM_END or an
+ error. However if all decompression is to be performed in a single step
+ (a single call of inflate), the parameter flush should be set to
+ Z_FINISH. In this case all pending input is processed and all pending
+ output is flushed; avail_out must be large enough to hold all the
+ uncompressed data. (The size of the uncompressed data may have been saved
+ by the compressor for this purpose.) The next operation on this stream must
+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+ is never required, but can be used to inform inflate that a faster routine
+ may be used for the single inflate() call.
+
+ inflate() returns Z_OK if some progress has been made (more input
+ processed or more output produced), Z_STREAM_END if the end of the
+ compressed data has been reached and all uncompressed output has been
+ produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if
+ the stream structure was inconsistent (for example if next_in or next_out
+ was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no
+ progress is possible or if there was not enough room in the output buffer
+ when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then
+ call inflateSync to look for a good compression block. */
+
+
+extern int inflateEnd OF((z_stream *strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any
+ pending output.
+
+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+ was inconsistent. In the error case, msg may be set but then points to a
+ static string (which must not be deallocated).
+*/
+
+ /* advanced functions */
+
+extern int inflateInit2 OF((z_stream *strm,
+ int windowBits));
+/*
+ This is another version of inflateInit with more compression options. The
+ fields next_out, zalloc and zfree must be initialized before by the caller.
+
+ The windowBits parameter is the base two logarithm of the maximum window
+ size (the size of the history buffer). It should be in the range 8..15 for
+ this version of the library (the value 16 will be allowed soon). The
+ default value is 15 if inflateInit is used instead. If a compressed stream
+ with a larger window size is given as input, inflate() will return with
+ the error code Z_DATA_ERROR instead of trying to allocate a larger window.
+
+ If next_out is not null, the library will use this buffer for the history
+ buffer; the buffer must either be large enough to hold the entire output
+ data, or have at least 1<<windowBits bytes. If next_out is null, the
+ library will allocate its own buffer (and leave next_out null). next_in
+ need not be provided here but must be provided by the application for the
+ next call of inflate().
+
+ If the history buffer is provided by the application, next_out must
+ never be changed by the application since the decompressor maintains
+ history information inside this buffer from call to call; the application
+ can only reset next_out to the beginning of the history buffer when
+ avail_out is zero and all output has been consumed.
+
+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
+ not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
+ windowBits < 8). msg is set to null if there is no error message.
+ inflateInit2 does not perform any decompression: this will be done by
+ inflate().
+*/
+
+extern int inflateSync OF((z_stream *strm));
+/*
+ Skips invalid compressed data until the special marker (see deflate()
+ above) can be found, or until all available input is skipped. No output
+ is provided.
+
+ inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR
+ if no more input was provided, Z_DATA_ERROR if no marker has been found,
+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+ case, the application may save the current current value of total_in which
+ indicates where valid compressed data was found. In the error case, the
+ application may repeatedly call inflateSync, providing more input each time,
+ until success or end of the input data.
+*/
+
+extern int inflateReset OF((z_stream *strm));
+/*
+ This function is equivalent to inflateEnd followed by inflateInit,
+ but does not free and reallocate all the internal decompression state.
+ The stream will keep attributes that may have been set by inflateInit2.
+
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+extern int inflateIncomp OF((z_stream *strm));
+/*
+ This function adds the data at next_in (avail_in bytes) to the output
+ history without performing any output. There must be no pending output,
+ and the decompressor must be expecting to see the start of a block.
+ Calling this function is equivalent to decompressing a stored block
+ containing the data at next_in (except that the data is not output).
+*/
+
+ /* checksum functions */
+
+/*
+ This function is not related to compression but is exported
+ anyway because it might be useful in applications using the
+ compression library.
+*/
+
+extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len));
+
+/*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+ return the updated checksum. If buf is NULL, this function returns
+ the required initial value for the checksum.
+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+ much faster. Usage example:
+
+ uLong adler = adler32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+*/
+
+#ifndef _Z_UTIL_H
+ struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+#endif /* _ZLIB_H */
+++ /dev/null
-static const unsigned char font[] = {
-/* 0x00 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0x01 */ 0x00,0x00,0x7E,0x81,0xA5,0x81,0x81,0xBD,0x99,0x81,0x81,0x7E,0x00,0x00,0x00,0x00,
-/* 0x02 */ 0x00,0x00,0x7E,0xFF,0xDB,0xFF,0xFF,0xC3,0xC3,0xE7,0xFF,0x7E,0x00,0x00,0x00,0x00,
-/* 0x03 */ 0x00,0x00,0x00,0x00,0x6C,0xFE,0xFE,0xFE,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00,
-/* 0x04 */ 0x00,0x00,0x00,0x00,0x10,0x38,0x7C,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00,0x00,
-/* 0x05 */ 0x00,0x00,0x00,0x18,0x3C,0x3C,0xE7,0xE7,0xE7,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
-/* 0x06 */ 0x00,0x00,0x00,0x18,0x3C,0x7E,0xFF,0xFF,0x7E,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
-/* 0x07 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0x08 */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0xC3,0xC3,0xE7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-/* 0x09 */ 0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x42,0x42,0x66,0x3C,0x00,0x00,0x00,0x00,0x00,
-/* 0x0A */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xC3,0x99,0xBD,0xBD,0x99,0xC3,0xFF,0xFF,0xFF,0xFF,0xFF,
-/* 0x0B */ 0x00,0x00,0x3E,0x0E,0x1A,0x32,0x78,0xCC,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00,
-/* 0x0C */ 0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,
-/* 0x0D */ 0x00,0x00,0x30,0x38,0x3C,0x36,0x33,0x30,0x30,0x70,0xF0,0xE0,0x00,0x00,0x00,0x00,
-/* 0x0E */ 0x00,0x00,0x7F,0x63,0x7F,0x63,0x63,0x63,0x63,0x67,0xE7,0xE6,0xC0,0x00,0x00,0x00,
-/* 0x0F */ 0x00,0x00,0x00,0x18,0x18,0xDB,0x3C,0xE7,0x3C,0xDB,0x18,0x18,0x00,0x00,0x00,0x00,
-/* 0x10 */ 0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFE,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,
-/* 0x11 */ 0x00,0x02,0x06,0x0E,0x1E,0x3E,0xFE,0x3E,0x1E,0x0E,0x06,0x02,0x00,0x00,0x00,0x00,
-/* 0x12 */ 0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,
-/* 0x13 */ 0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00,
-/* 0x14 */ 0x00,0x00,0x7F,0xDB,0xDB,0xDB,0x7B,0x1B,0x1B,0x1B,0x1B,0x1B,0x00,0x00,0x00,0x00,
-/* 0x15 */ 0x00,0x7C,0xC6,0x60,0x38,0x6C,0xC6,0xC6,0x6C,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00,
-/* 0x16 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFE,0xFE,0x00,0x00,0x00,0x00,
-/* 0x17 */ 0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x7E,0x3C,0x18,0x7E,0x00,0x00,0x00,0x00,
-/* 0x18 */ 0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
-/* 0x19 */ 0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,
-/* 0x1A */ 0x00,0x00,0x00,0x00,0x00,0x18,0x0C,0xFE,0x0C,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0x1B */ 0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xFE,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0x1C */ 0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0x1D */ 0x00,0x00,0x00,0x00,0x00,0x28,0x6C,0xFE,0x6C,0x28,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0x1E */ 0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7C,0x7C,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,
-/* 0x1F */ 0x00,0x00,0x00,0x00,0xFE,0xFE,0x7C,0x7C,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00,
-/* 0x20 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0x21 */ 0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
-/* 0x22 */ 0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0x23 */ 0x00,0x00,0x00,0x6C,0x6C,0xFE,0x6C,0x6C,0x6C,0xFE,0x6C,0x6C,0x00,0x00,0x00,0x00,
-/* 0x24 */ 0x18,0x18,0x7C,0xC6,0xC2,0xC0,0x7C,0x06,0x06,0x86,0xC6,0x7C,0x18,0x18,0x00,0x00,
-/* 0x25 */ 0x00,0x00,0x00,0x00,0xC2,0xC6,0x0C,0x18,0x30,0x60,0xC6,0x86,0x00,0x00,0x00,0x00,
-/* 0x26 */ 0x00,0x00,0x38,0x6C,0x6C,0x38,0x76,0xDC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
-/* 0x27 */ 0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0x28 */ 0x00,0x00,0x0C,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0C,0x00,0x00,0x00,0x00,
-/* 0x29 */ 0x00,0x00,0x30,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x30,0x00,0x00,0x00,0x00,
-/* 0x2A */ 0x00,0x00,0x00,0x00,0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0x2B */ 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0x2C */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00,
-/* 0x2D */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0x2E */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
-/* 0x2F */ 0x00,0x00,0x00,0x00,0x02,0x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00,0x00,0x00,0x00,
-/* 0x30 */ 0x00,0x00,0x38,0x6C,0xC6,0xC6,0xD6,0xD6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00,
-/* 0x31 */ 0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00,
-/* 0x32 */ 0x00,0x00,0x7C,0xC6,0x06,0x0C,0x18,0x30,0x60,0xC0,0xC6,0xFE,0x00,0x00,0x00,0x00,
-/* 0x33 */ 0x00,0x00,0x7C,0xC6,0x06,0x06,0x3C,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0x34 */ 0x00,0x00,0x0C,0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00,
-/* 0x35 */ 0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xFC,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0x36 */ 0x00,0x00,0x38,0x60,0xC0,0xC0,0xFC,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0x37 */ 0x00,0x00,0xFE,0xC6,0x06,0x06,0x0C,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,
-/* 0x38 */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0x39 */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00,
-/* 0x3A */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
-/* 0x3B */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00,
-/* 0x3C */ 0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00,
-/* 0x3D */ 0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0x3E */ 0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00,
-/* 0x3F */ 0x00,0x00,0x7C,0xC6,0xC6,0x0C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
-/* 0x40 */ 0x00,0x00,0x00,0x7C,0xC6,0xC6,0xDE,0xDE,0xDE,0xDC,0xC0,0x7C,0x00,0x00,0x00,0x00,
-/* 0x41 */ 0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
-/* 0x42 */ 0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x66,0x66,0x66,0x66,0xFC,0x00,0x00,0x00,0x00,
-/* 0x43 */ 0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x00,0x00,0x00,0x00,
-/* 0x44 */ 0x00,0x00,0xF8,0x6C,0x66,0x66,0x66,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00,
-/* 0x45 */ 0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00,
-/* 0x46 */ 0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
-/* 0x47 */ 0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xDE,0xC6,0xC6,0x66,0x3A,0x00,0x00,0x00,0x00,
-/* 0x48 */ 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
-/* 0x49 */ 0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
-/* 0x4A */ 0x00,0x00,0x1E,0x0C,0x0C,0x0C,0x0C,0x0C,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00,
-/* 0x4B */ 0x00,0x00,0xE6,0x66,0x66,0x6C,0x78,0x78,0x6C,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,
-/* 0x4C */ 0x00,0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00,
-/* 0x4D */ 0x00,0x00,0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
-/* 0x4E */ 0x00,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
-/* 0x4F */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0x50 */ 0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
-/* 0x51 */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xDE,0x7C,0x0C,0x0E,0x00,0x00,
-/* 0x52 */ 0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x6C,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,
-/* 0x53 */ 0x00,0x00,0x7C,0xC6,0xC6,0x60,0x38,0x0C,0x06,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0x54 */ 0x00,0x00,0x7E,0x7E,0x5A,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
-/* 0x55 */ 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0x56 */ 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x10,0x00,0x00,0x00,0x00,
-/* 0x57 */ 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0xEE,0x6C,0x00,0x00,0x00,0x00,
-/* 0x58 */ 0x00,0x00,0xC6,0xC6,0x6C,0x7C,0x38,0x38,0x7C,0x6C,0xC6,0xC6,0x00,0x00,0x00,0x00,
-/* 0x59 */ 0x00,0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
-/* 0x5A */ 0x00,0x00,0xFE,0xC6,0x86,0x0C,0x18,0x30,0x60,0xC2,0xC6,0xFE,0x00,0x00,0x00,0x00,
-/* 0x5B */ 0x00,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00,
-/* 0x5C */ 0x00,0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x06,0x02,0x00,0x00,0x00,0x00,
-/* 0x5D */ 0x00,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00,
-/* 0x5E */ 0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0x5F */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,
-/* 0x60 */ 0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0x61 */ 0x00,0x00,0x00,0x00,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
-/* 0x62 */ 0x00,0x00,0xE0,0x60,0x60,0x78,0x6C,0x66,0x66,0x66,0x66,0x7C,0x00,0x00,0x00,0x00,
-/* 0x63 */ 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0x64 */ 0x00,0x00,0x1C,0x0C,0x0C,0x3C,0x6C,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
-/* 0x65 */ 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0x66 */ 0x00,0x00,0x38,0x6C,0x64,0x60,0xF0,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
-/* 0x67 */ 0x00,0x00,0x00,0x00,0x00,0x3E,0x66,0x66,0x66,0x66,0x66,0x3E,0x06,0x66,0x3C,0x00,
-/* 0x68 */ 0x00,0x00,0xE0,0x60,0x60,0x6C,0x76,0x66,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,
-/* 0x69 */ 0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
-/* 0x6A */ 0x00,0x00,0x06,0x06,0x00,0x0E,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00,
-/* 0x6B */ 0x00,0x00,0xE0,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0xE6,0x00,0x00,0x00,0x00,
-/* 0x6C */ 0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
-/* 0x6D */ 0x00,0x00,0x00,0x00,0x00,0x6C,0xFE,0xD6,0xD6,0xD6,0xC6,0xC6,0x00,0x00,0x00,0x00,
-/* 0x6E */ 0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
-/* 0x6F */ 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0x70 */ 0x00,0x00,0x00,0x00,0x00,0xFC,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00,
-/* 0x71 */ 0x00,0x00,0x00,0x00,0x00,0x7E,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0x0C,0x1E,0x00,
-/* 0x72 */ 0x00,0x00,0x00,0x00,0x00,0xDC,0x76,0x66,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
-/* 0x73 */ 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0x60,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0x74 */ 0x00,0x00,0x10,0x30,0x30,0xFC,0x30,0x30,0x30,0x30,0x36,0x1C,0x00,0x00,0x00,0x00,
-/* 0x75 */ 0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
-/* 0x76 */ 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0x00,0x00,
-/* 0x77 */ 0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0x6C,0x00,0x00,0x00,0x00,
-/* 0x78 */ 0x00,0x00,0x00,0x00,0x00,0xC6,0x6C,0x38,0x38,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,
-/* 0x79 */ 0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00,
-/* 0x7A */ 0x00,0x00,0x00,0x00,0x00,0xFE,0xCC,0x18,0x30,0x60,0xC6,0xFE,0x00,0x00,0x00,0x00,
-/* 0x7B */ 0x00,0x00,0x0E,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00,
-/* 0x7C */ 0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
-/* 0x7D */ 0x00,0x00,0x70,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00,
-/* 0x7E */ 0x00,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0x7F */ 0x00,0x00,0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0x00,0x00,0x00,0x00,0x00,
-/* 0x80 */ 0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x0C,0x06,0x7C,0x00,0x00,
-/* 0x81 */ 0x00,0x00,0xCC,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
-/* 0x82 */ 0x00,0x0C,0x18,0x30,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0x83 */ 0x00,0x10,0x38,0x6C,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
-/* 0x84 */ 0x00,0x00,0xCC,0x00,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
-/* 0x85 */ 0x00,0x60,0x30,0x18,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
-/* 0x86 */ 0x00,0x38,0x6C,0x38,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
-/* 0x87 */ 0x00,0x00,0x00,0x00,0x3C,0x66,0x60,0x60,0x66,0x3C,0x0C,0x06,0x3C,0x00,0x00,0x00,
-/* 0x88 */ 0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0x89 */ 0x00,0x00,0xC6,0x00,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0x8A */ 0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0x8B */ 0x00,0x00,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
-/* 0x8C */ 0x00,0x18,0x3C,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
-/* 0x8D */ 0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
-/* 0x8E */ 0x00,0xC6,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
-/* 0x8F */ 0x38,0x6C,0x38,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
-/* 0x90 */ 0x18,0x30,0x60,0x00,0xFE,0x66,0x60,0x7C,0x60,0x60,0x66,0xFE,0x00,0x00,0x00,0x00,
-/* 0x91 */ 0x00,0x00,0x00,0x00,0x00,0xCC,0x76,0x36,0x7E,0xD8,0xD8,0x6E,0x00,0x00,0x00,0x00,
-/* 0x92 */ 0x00,0x00,0x3E,0x6C,0xCC,0xCC,0xFE,0xCC,0xCC,0xCC,0xCC,0xCE,0x00,0x00,0x00,0x00,
-/* 0x93 */ 0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0x94 */ 0x00,0x00,0xC6,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0x95 */ 0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0x96 */ 0x00,0x30,0x78,0xCC,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
-/* 0x97 */ 0x00,0x60,0x30,0x18,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
-/* 0x98 */ 0x00,0x00,0xC6,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0x78,0x00,
-/* 0x99 */ 0x00,0xC6,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0x9A */ 0x00,0xC6,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0x9B */ 0x00,0x18,0x18,0x3C,0x66,0x60,0x60,0x60,0x66,0x3C,0x18,0x18,0x00,0x00,0x00,0x00,
-/* 0x9C */ 0x00,0x38,0x6C,0x64,0x60,0xF8,0x60,0x60,0x60,0x60,0xE6,0xFC,0x00,0x00,0x00,0x00,
-/* 0x9D */ 0x00,0x00,0x66,0x66,0x3C,0x18,0x7E,0x18,0x7E,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
-/* 0x9E */ 0x00,0xF8,0xCC,0xCC,0xF8,0xC4,0xCC,0xDE,0xCC,0xCC,0xCC,0xC6,0x00,0x00,0x00,0x00,
-/* 0x9F */ 0x00,0x0E,0x1B,0x18,0x18,0x18,0x7E,0x18,0x18,0x18,0x18,0x18,0xD8,0x70,0x00,0x00,
-/* 0xA0 */ 0x00,0x18,0x30,0x60,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
-/* 0xA1 */ 0x00,0x0C,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
-/* 0xA2 */ 0x00,0x18,0x30,0x60,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0xA3 */ 0x00,0x18,0x30,0x60,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
-/* 0xA4 */ 0x00,0x00,0x76,0xDC,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
-/* 0xA5 */ 0x76,0xDC,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
-/* 0xA6 */ 0x00,0x3C,0x6C,0x6C,0x3E,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xA7 */ 0x00,0x38,0x6C,0x6C,0x38,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xA8 */ 0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0xC0,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
-/* 0xA9 */ 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,
-/* 0xAA */ 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00,
-/* 0xAB */ 0x00,0xC0,0xC0,0xC2,0xC6,0xCC,0x18,0x30,0x60,0xDC,0x86,0x0C,0x18,0x3E,0x00,0x00,
-/* 0xAC */ 0x00,0xC0,0xC0,0xC2,0xC6,0xCC,0x18,0x30,0x66,0xCE,0x9E,0x3E,0x06,0x06,0x00,0x00,
-/* 0xAD */ 0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3C,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00,
-/* 0xAE */ 0x00,0x00,0x00,0x00,0x00,0x36,0x6C,0xD8,0x6C,0x36,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xAF */ 0x00,0x00,0x00,0x00,0x00,0xD8,0x6C,0x36,0x6C,0xD8,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xB0 */ 0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,
-/* 0xB1 */ 0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,
-/* 0xB2 */ 0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,
-/* 0xB3 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* 0xB4 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* 0xB5 */ 0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* 0xB6 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* 0xB7 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* 0xB8 */ 0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* 0xB9 */ 0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* 0xBA */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* 0xBB */ 0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* 0xBC */ 0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xBD */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xBE */ 0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xBF */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* 0xC0 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xC1 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xC2 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* 0xC3 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* 0xC4 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xC5 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* 0xC6 */ 0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* 0xC7 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* 0xC8 */ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xC9 */ 0x00,0x00,0x00,0x00,0x00,0x3F,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* 0xCA */ 0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xCB */ 0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* 0xCC */ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* 0xCD */ 0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xCE */ 0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* 0xCF */ 0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xD0 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xD1 */ 0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* 0xD2 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* 0xD3 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xD4 */ 0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xD5 */ 0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* 0xD6 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* 0xD7 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* 0xD8 */ 0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* 0xD9 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xDA */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* 0xDB */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-/* 0xDC */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-/* 0xDD */ 0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
-/* 0xDE */ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
-/* 0xDF */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xE0 */ 0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0xD8,0xD8,0xD8,0xDC,0x76,0x00,0x00,0x00,0x00,
-/* 0xE1 */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xFC,0xC6,0xC6,0xC6,0xC6,0xDC,0xC0,0xC0,0x00,0x00,
-/* 0xE2 */ 0x00,0x00,0xFE,0xC6,0xC6,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,
-/* 0xE3 */ 0x00,0x00,0x00,0x00,0x00,0xFE,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,
-/* 0xE4 */ 0x00,0x00,0xFE,0xC6,0x60,0x30,0x18,0x18,0x30,0x60,0xC6,0xFE,0x00,0x00,0x00,0x00,
-/* 0xE5 */ 0x00,0x00,0x00,0x00,0x00,0x7E,0xD8,0xD8,0xD8,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00,
-/* 0xE6 */ 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0xC0,0x00,0x00,0x00,
-/* 0xE7 */ 0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
-/* 0xE8 */ 0x00,0x00,0x7E,0x18,0x3C,0x66,0x66,0x66,0x66,0x3C,0x18,0x7E,0x00,0x00,0x00,0x00,
-/* 0xE9 */ 0x00,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00,
-/* 0xEA */ 0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0x6C,0x6C,0x6C,0x6C,0xEE,0x00,0x00,0x00,0x00,
-/* 0xEB */ 0x00,0x00,0x1E,0x30,0x18,0x0C,0x3E,0x66,0x66,0x66,0x66,0x3C,0x00,0x00,0x00,0x00,
-/* 0xEC */ 0x00,0x00,0x00,0x00,0x00,0x7E,0xDB,0xDB,0xDB,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xED */ 0x00,0x00,0x00,0x03,0x06,0x7E,0xDB,0xDB,0xF3,0x7E,0x60,0xC0,0x00,0x00,0x00,0x00,
-/* 0xEE */ 0x00,0x00,0x1C,0x30,0x60,0x60,0x7C,0x60,0x60,0x60,0x30,0x1C,0x00,0x00,0x00,0x00,
-/* 0xEF */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
-/* 0xF0 */ 0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,
-/* 0xF1 */ 0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,
-/* 0xF2 */ 0x00,0x00,0x00,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00,0x7E,0x00,0x00,0x00,0x00,
-/* 0xF3 */ 0x00,0x00,0x00,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00,0x7E,0x00,0x00,0x00,0x00,
-/* 0xF4 */ 0x00,0x0E,0x1B,0x1B,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* 0xF5 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xD8,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00,
-/* 0xF6 */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x7E,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
-/* 0xF7 */ 0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xF8 */ 0x00,0x38,0x6C,0x6C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xF9 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xFA */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xFB */ 0x00,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0xEC,0x6C,0x6C,0x3C,0x1C,0x00,0x00,0x00,0x00,
-/* 0xFC */ 0x00,0xD8,0x6C,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xFD */ 0x00,0x70,0xD8,0x30,0x60,0xC8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* 0xFE */ 0x00,0x00,0x00,0x00,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x00,0x00,0x00,0x00,0x00,
-};
+++ /dev/null
-#include <linux/keyboard.h>
-
-#include <../drivers/char/defkeymap.c> /* yeah I know it's bad -- Cort */
-
-
-unsigned char shfts, ctls, alts, caps;
-
-#define KBDATAP 0x60 /* kbd data port */
-#define KBSTATUSPORT 0x61 /* kbd status */
-#define KBSTATP 0x64 /* kbd status port */
-#define KBINRDY 0x01
-#define KBOUTRDY 0x02
-
-
-static int kbd(int noblock)
-{
- unsigned char dt, brk, val;
- unsigned code;
-loop:
- if (noblock) {
- if ((inb(KBSTATP) & KBINRDY) == 0)
- return (-1);
- } else while((inb(KBSTATP) & KBINRDY) == 0) ;
-
- dt = inb(KBDATAP);
-
- brk = dt & 0x80; /* brk == 1 on key release */
- dt = dt & 0x7f; /* keycode */
-
- if (shfts)
- code = shift_map[dt];
- else if (ctls)
- code = ctrl_map[dt];
- else
- code = plain_map[dt];
-
- val = KVAL(code);
- switch (KTYP(code) & 0x0f) {
- case KT_LATIN:
- if (brk)
- break;
- if (alts)
- val |= 0x80;
- if (val == 0x7f) /* map delete to backspace */
- val = '\b';
- return val;
-
- case KT_LETTER:
- if (brk)
- break;
- if (caps)
- val -= 'a'-'A';
- return val;
-
- case KT_SPEC:
- if (brk)
- break;
- if (val == KVAL(K_CAPS))
- caps = !caps;
- else if (val == KVAL(K_ENTER)) {
-enter: /* Wait for key up */
- while (1) {
- while((inb(KBSTATP) & KBINRDY) == 0) ;
- dt = inb(KBDATAP);
- if (dt & 0x80) /* key up */ break;
- }
- return 10;
- }
- break;
-
- case KT_PAD:
- if (brk)
- break;
- if (val < 10)
- return val;
- if (val == KVAL(K_PENTER))
- goto enter;
- break;
-
- case KT_SHIFT:
- switch (val) {
- case KG_SHIFT:
- case KG_SHIFTL:
- case KG_SHIFTR:
- shfts = brk ? 0 : 1;
- break;
- case KG_ALT:
- case KG_ALTGR:
- alts = brk ? 0 : 1;
- break;
- case KG_CTRL:
- case KG_CTRLL:
- case KG_CTRLR:
- ctls = brk ? 0 : 1;
- break;
- }
- break;
-
- case KT_LOCK:
- switch (val) {
- case KG_SHIFT:
- case KG_SHIFTL:
- case KG_SHIFTR:
- if (brk)
- shfts = !shfts;
- break;
- case KG_ALT:
- case KG_ALTGR:
- if (brk)
- alts = !alts;
- break;
- case KG_CTRL:
- case KG_CTRLL:
- case KG_CTRLR:
- if (brk)
- ctls = !ctls;
- break;
- }
- break;
- }
- if (brk) return (-1); /* Ignore initial 'key up' codes */
- goto loop;
-}
-
-static void kbdreset(void)
-{
- unsigned char c;
- int i;
-
- /* flush input queue */
- while ((inb(KBSTATP) & KBINRDY))
- {
- (void)inb(KBDATAP);
- }
- /* Send self-test */
- while (inb(KBSTATP) & KBOUTRDY) ;
- outb(KBSTATP,0xAA);
- while ((inb(KBSTATP) & KBINRDY) == 0) ; /* wait input ready */
- if ((c = inb(KBDATAP)) != 0x55)
- {
- puts("Keyboard self test failed - result:");
- puthex(c);
- puts("\n");
- }
- /* Enable interrupts and keyboard controller */
- while (inb(KBSTATP) & KBOUTRDY) ;
- outb(KBSTATP,0x60);
- while (inb(KBSTATP) & KBOUTRDY) ;
- outb(KBDATAP,0x45);
- for (i = 0; i < 10000; i++) udelay(1);
-
- while (inb(KBSTATP) & KBOUTRDY) ;
- outb(KBSTATP,0x20);
- while ((inb(KBSTATP) & KBINRDY) == 0) ; /* wait input ready */
- if (! (inb(KBDATAP) & 0x40)) {
- /*
- * Quote from PS/2 System Reference Manual:
- *
- * "Address hex 0060 and address hex 0064 should be
- * written only when the input-buffer-full bit and
- * output-buffer-full bit in the Controller Status
- * register are set 0." (KBINRDY and KBOUTRDY)
- */
-
- while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) ;
- outb(KBDATAP,0xF0);
- while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) ;
- outb(KBDATAP,0x01);
- }
-
- while (inb(KBSTATP) & KBOUTRDY) ;
- outb(KBSTATP,0xAE);
-}
-
-/* We have to actually read the keyboard when CRT_tstc is called,
- * since the pending data might be a key release code, and therefore
- * not valid data. In this case, kbd() will return -1, even though there's
- * data to be read. Of course, we might actually read a valid key press,
- * in which case it gets queued into key_pending for use by CRT_getc.
- */
-
-static int kbd_reset = 0;
-
-static int key_pending = -1;
-
-int CRT_getc(void)
-{
- int c;
- if (!kbd_reset) {kbdreset(); kbd_reset++; }
-
- if (key_pending != -1) {
- c = key_pending;
- key_pending = -1;
- return c;
- } else {
- while ((c = kbd(0)) == 0) ;
- return c;
- }
-}
-
-int CRT_tstc(void)
-{
- if (!kbd_reset) {kbdreset(); kbd_reset++; }
-
- while (key_pending == -1 && ((inb(KBSTATP) & KBINRDY) != 0)) {
- key_pending = kbd(1);
- }
-
- return (key_pending != -1);
-}
--- /dev/null
+#
+# Makefile for some libs needed by zImage.
+#
+
+L_TARGET := zlib.a
+
+obj-y := zlib.o
+
+include $(TOPDIR)/Rules.make
--- /dev/null
+/*
+ * BK Id: SCCS/s.zlib.c 1.8 05/18/01 15:17:24 cort
+ */
+/*
+ * This file is derived from various .h and .c files from the zlib-0.95
+ * distribution by Jean-loup Gailly and Mark Adler, with some additions
+ * by Paul Mackerras to aid in implementing Deflate compression and
+ * decompression for PPP packets. See zlib.h for conditions of
+ * distribution and use.
+ *
+ * Changes that have been made include:
+ * - changed functions not used outside this file to "local"
+ * - added minCompression parameter to deflateInit2
+ * - added Z_PACKET_FLUSH (see zlib.h for details)
+ * - added inflateIncomp
+ *
+ */
+
+/*+++++*/
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* From: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp */
+
+#define _Z_UTIL_H
+
+#include "zlib.h"
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+#define FAR
+
+typedef unsigned char uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long ulg;
+
+extern char *z_errmsg[]; /* indexed by 1-zlib_error */
+
+#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err)
+/* To be used only when the state is known to be valid */
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+ /* common constants */
+
+#define DEFLATED 8
+
+#ifndef DEF_WBITS
+# define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES 2
+/* The three kinds of block type */
+
+#define MIN_MATCH 3
+#define MAX_MATCH 258
+/* The minimum and maximum match lengths */
+
+ /* functions */
+
+#include <linux/string.h>
+#define zmemcpy memcpy
+#define zmemzero(dest, len) memset(dest, 0, len)
+
+/* Diagnostic functions */
+#ifdef DEBUG_ZLIB
+# include <stdio.h>
+# ifndef verbose
+# define verbose 0
+# endif
+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+# define Trace(x) fprintf x
+# define Tracev(x) {if (verbose) fprintf x ;}
+# define Tracevv(x) {if (verbose>1) fprintf x ;}
+# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+# define Assert(cond,msg)
+# define Trace(x)
+# define Tracev(x)
+# define Tracevv(x)
+# define Tracec(c,x)
+# define Tracecv(c,x)
+#endif
+
+
+typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len));
+
+/* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */
+/* void zcfree OF((voidpf opaque, voidpf ptr)); */
+
+#define ZALLOC(strm, items, size) \
+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr, size) \
+ (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size))
+#define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);}
+
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/*+++++*/
+/* infblock.h -- header to use infblock.c
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+struct inflate_blocks_state;
+typedef struct inflate_blocks_state FAR inflate_blocks_statef;
+
+local inflate_blocks_statef * inflate_blocks_new OF((
+ z_stream *z,
+ check_func c, /* check function */
+ uInt w)); /* window size */
+
+local int inflate_blocks OF((
+ inflate_blocks_statef *,
+ z_stream *,
+ int)); /* initial return code */
+
+local void inflate_blocks_reset OF((
+ inflate_blocks_statef *,
+ z_stream *,
+ uLongf *)); /* check value on output */
+
+local int inflate_blocks_free OF((
+ inflate_blocks_statef *,
+ z_stream *,
+ uLongf *)); /* check value on output */
+
+local int inflate_addhistory OF((
+ inflate_blocks_statef *,
+ z_stream *));
+
+local int inflate_packet_flush OF((
+ inflate_blocks_statef *));
+
+/*+++++*/
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* Huffman code lookup table entry--this entry is four bytes for machines
+ that have 16-bit pointers (e.g. PC's in the small or medium model). */
+
+typedef struct inflate_huft_s FAR inflate_huft;
+
+struct inflate_huft_s {
+ union {
+ struct {
+ Byte Exop; /* number of extra bits or operation */
+ Byte Bits; /* number of bits in this code or subcode */
+ } what;
+ uInt Nalloc; /* number of these allocated here */
+ Bytef *pad; /* pad structure to a power of 2 (4 bytes for */
+ } word; /* 16-bit, 8 bytes for 32-bit machines) */
+ union {
+ uInt Base; /* literal, length base, or distance base */
+ inflate_huft *Next; /* pointer to next level of table */
+ } more;
+};
+
+#ifdef DEBUG_ZLIB
+ local uInt inflate_hufts;
+#endif
+
+local int inflate_trees_bits OF((
+ uIntf *, /* 19 code lengths */
+ uIntf *, /* bits tree desired/actual depth */
+ inflate_huft * FAR *, /* bits tree result */
+ z_stream *)); /* for zalloc, zfree functions */
+
+local int inflate_trees_dynamic OF((
+ uInt, /* number of literal/length codes */
+ uInt, /* number of distance codes */
+ uIntf *, /* that many (total) code lengths */
+ uIntf *, /* literal desired/actual bit depth */
+ uIntf *, /* distance desired/actual bit depth */
+ inflate_huft * FAR *, /* literal/length tree result */
+ inflate_huft * FAR *, /* distance tree result */
+ z_stream *)); /* for zalloc, zfree functions */
+
+local int inflate_trees_fixed OF((
+ uIntf *, /* literal desired/actual bit depth */
+ uIntf *, /* distance desired/actual bit depth */
+ inflate_huft * FAR *, /* literal/length tree result */
+ inflate_huft * FAR *)); /* distance tree result */
+
+local int inflate_trees_free OF((
+ inflate_huft *, /* tables to free */
+ z_stream *)); /* for zfree function */
+
+
+/*+++++*/
+/* infcodes.h -- header to use infcodes.c
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+struct inflate_codes_state;
+typedef struct inflate_codes_state FAR inflate_codes_statef;
+
+local inflate_codes_statef *inflate_codes_new OF((
+ uInt, uInt,
+ inflate_huft *, inflate_huft *,
+ z_stream *));
+
+local int inflate_codes OF((
+ inflate_blocks_statef *,
+ z_stream *,
+ int));
+
+local void inflate_codes_free OF((
+ inflate_codes_statef *,
+ z_stream *));
+
+
+/*+++++*/
+/* inflate.c -- zlib interface to inflate modules
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* inflate private state */
+struct internal_state {
+
+ /* mode */
+ enum {
+ METHOD, /* waiting for method byte */
+ FLAG, /* waiting for flag byte */
+ BLOCKS, /* decompressing blocks */
+ CHECK4, /* four check bytes to go */
+ CHECK3, /* three check bytes to go */
+ CHECK2, /* two check bytes to go */
+ CHECK1, /* one check byte to go */
+ DONE, /* finished check, done */
+ BAD} /* got an error--stay here */
+ mode; /* current inflate mode */
+
+ /* mode dependent information */
+ union {
+ uInt method; /* if FLAGS, method byte */
+ struct {
+ uLong was; /* computed check value */
+ uLong need; /* stream check value */
+ } check; /* if CHECK, check values to compare */
+ uInt marker; /* if BAD, inflateSync's marker bytes count */
+ } sub; /* submode */
+
+ /* mode independent information */
+ int nowrap; /* flag for no wrapper */
+ uInt wbits; /* log2(window size) (8..15, defaults to 15) */
+ inflate_blocks_statef
+ *blocks; /* current inflate_blocks state */
+
+};
+
+
+int inflateReset(z)
+z_stream *z;
+{
+ uLong c;
+
+ if (z == Z_NULL || z->state == Z_NULL)
+ return Z_STREAM_ERROR;
+ z->total_in = z->total_out = 0;
+ z->msg = Z_NULL;
+ z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
+ inflate_blocks_reset(z->state->blocks, z, &c);
+ Trace((stderr, "inflate: reset\n"));
+ return Z_OK;
+}
+
+
+int inflateEnd(z)
+z_stream *z;
+{
+ uLong c;
+
+ if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
+ return Z_STREAM_ERROR;
+ if (z->state->blocks != Z_NULL)
+ inflate_blocks_free(z->state->blocks, z, &c);
+ ZFREE(z, z->state, sizeof(struct internal_state));
+ z->state = Z_NULL;
+ Trace((stderr, "inflate: end\n"));
+ return Z_OK;
+}
+
+
+int inflateInit2(z, w)
+z_stream *z;
+int w;
+{
+ /* initialize state */
+ if (z == Z_NULL)
+ return Z_STREAM_ERROR;
+/* if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */
+/* if (z->zfree == Z_NULL) z->zfree = zcfree; */
+ if ((z->state = (struct internal_state FAR *)
+ ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
+ return Z_MEM_ERROR;
+ z->state->blocks = Z_NULL;
+
+ /* handle undocumented nowrap option (no zlib header or check) */
+ z->state->nowrap = 0;
+ if (w < 0)
+ {
+ w = - w;
+ z->state->nowrap = 1;
+ }
+
+ /* set window size */
+ if (w < 8 || w > 15)
+ {
+ inflateEnd(z);
+ return Z_STREAM_ERROR;
+ }
+ z->state->wbits = (uInt)w;
+
+ /* create inflate_blocks state */
+ if ((z->state->blocks =
+ inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w))
+ == Z_NULL)
+ {
+ inflateEnd(z);
+ return Z_MEM_ERROR;
+ }
+ Trace((stderr, "inflate: allocated\n"));
+
+ /* reset state */
+ inflateReset(z);
+ return Z_OK;
+}
+
+
+int inflateInit(z)
+z_stream *z;
+{
+ return inflateInit2(z, DEF_WBITS);
+}
+
+
+#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;}
+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
+
+int inflate(z, f)
+z_stream *z;
+int f;
+{
+ int r;
+ uInt b;
+
+ if (z == Z_NULL || z->next_in == Z_NULL)
+ return Z_STREAM_ERROR;
+ r = Z_BUF_ERROR;
+ while (1) switch (z->state->mode)
+ {
+ case METHOD:
+ NEEDBYTE
+ if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED)
+ {
+ z->state->mode = BAD;
+ z->msg = "unknown compression method";
+ z->state->sub.marker = 5; /* can't try inflateSync */
+ break;
+ }
+ if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
+ {
+ z->state->mode = BAD;
+ z->msg = "invalid window size";
+ z->state->sub.marker = 5; /* can't try inflateSync */
+ break;
+ }
+ z->state->mode = FLAG;
+ case FLAG:
+ NEEDBYTE
+ if ((b = NEXTBYTE) & 0x20)
+ {
+ z->state->mode = BAD;
+ z->msg = "invalid reserved bit";
+ z->state->sub.marker = 5; /* can't try inflateSync */
+ break;
+ }
+ if (((z->state->sub.method << 8) + b) % 31)
+ {
+ z->state->mode = BAD;
+ z->msg = "incorrect header check";
+ z->state->sub.marker = 5; /* can't try inflateSync */
+ break;
+ }
+ Trace((stderr, "inflate: zlib header ok\n"));
+ z->state->mode = BLOCKS;
+ case BLOCKS:
+ r = inflate_blocks(z->state->blocks, z, r);
+ if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0)
+ r = inflate_packet_flush(z->state->blocks);
+ if (r == Z_DATA_ERROR)
+ {
+ z->state->mode = BAD;
+ z->state->sub.marker = 0; /* can try inflateSync */
+ break;
+ }
+ if (r != Z_STREAM_END)
+ return r;
+ r = Z_OK;
+ inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
+ if (z->state->nowrap)
+ {
+ z->state->mode = DONE;
+ break;
+ }
+ z->state->mode = CHECK4;
+ case CHECK4:
+ NEEDBYTE
+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
+ z->state->mode = CHECK3;
+ case CHECK3:
+ NEEDBYTE
+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
+ z->state->mode = CHECK2;
+ case CHECK2:
+ NEEDBYTE
+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
+ z->state->mode = CHECK1;
+ case CHECK1:
+ NEEDBYTE
+ z->state->sub.check.need += (uLong)NEXTBYTE;
+
+ if (z->state->sub.check.was != z->state->sub.check.need)
+ {
+ z->state->mode = BAD;
+ z->msg = "incorrect data check";
+ z->state->sub.marker = 5; /* can't try inflateSync */
+ break;
+ }
+ Trace((stderr, "inflate: zlib check ok\n"));
+ z->state->mode = DONE;
+ case DONE:
+ return Z_STREAM_END;
+ case BAD:
+ return Z_DATA_ERROR;
+ default:
+ return Z_STREAM_ERROR;
+ }
+
+ empty:
+ if (f != Z_PACKET_FLUSH)
+ return r;
+ z->state->mode = BAD;
+ z->state->sub.marker = 0; /* can try inflateSync */
+ return Z_DATA_ERROR;
+}
+
+/*
+ * This subroutine adds the data at next_in/avail_in to the output history
+ * without performing any output. The output buffer must be "caught up";
+ * i.e. no pending output (hence s->read equals s->write), and the state must
+ * be BLOCKS (i.e. we should be willing to see the start of a series of
+ * BLOCKS). On exit, the output will also be caught up, and the checksum
+ * will have been updated if need be.
+ */
+
+int inflateIncomp(z)
+z_stream *z;
+{
+ if (z->state->mode != BLOCKS)
+ return Z_DATA_ERROR;
+ return inflate_addhistory(z->state->blocks, z);
+}
+
+
+int inflateSync(z)
+z_stream *z;
+{
+ uInt n; /* number of bytes to look at */
+ Bytef *p; /* pointer to bytes */
+ uInt m; /* number of marker bytes found in a row */
+ uLong r, w; /* temporaries to save total_in and total_out */
+
+ /* set up */
+ if (z == Z_NULL || z->state == Z_NULL)
+ return Z_STREAM_ERROR;
+ if (z->state->mode != BAD)
+ {
+ z->state->mode = BAD;
+ z->state->sub.marker = 0;
+ }
+ if ((n = z->avail_in) == 0)
+ return Z_BUF_ERROR;
+ p = z->next_in;
+ m = z->state->sub.marker;
+
+ /* search */
+ while (n && m < 4)
+ {
+ if (*p == (Byte)(m < 2 ? 0 : 0xff))
+ m++;
+ else if (*p)
+ m = 0;
+ else
+ m = 4 - m;
+ p++, n--;
+ }
+
+ /* restore */
+ z->total_in += p - z->next_in;
+ z->next_in = p;
+ z->avail_in = n;
+ z->state->sub.marker = m;
+
+ /* return no joy or set up to restart on a new block */
+ if (m != 4)
+ return Z_DATA_ERROR;
+ r = z->total_in; w = z->total_out;
+ inflateReset(z);
+ z->total_in = r; z->total_out = w;
+ z->state->mode = BLOCKS;
+ return Z_OK;
+}
+
+#undef NEEDBYTE
+#undef NEXTBYTE
+
+/*+++++*/
+/* infutil.h -- types and macros common to blocks and codes
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* inflate blocks semi-private state */
+struct inflate_blocks_state {
+
+ /* mode */
+ enum {
+ TYPE, /* get type bits (3, including end bit) */
+ LENS, /* get lengths for stored */
+ STORED, /* processing stored block */
+ TABLE, /* get table lengths */
+ BTREE, /* get bit lengths tree for a dynamic block */
+ DTREE, /* get length, distance trees for a dynamic block */
+ CODES, /* processing fixed or dynamic block */
+ DRY, /* output remaining window bytes */
+ DONEB, /* finished last block, done */
+ BADB} /* got a data error--stuck here */
+ mode; /* current inflate_block mode */
+
+ /* mode dependent information */
+ union {
+ uInt left; /* if STORED, bytes left to copy */
+ struct {
+ uInt table; /* table lengths (14 bits) */
+ uInt index; /* index into blens (or border) */
+ uIntf *blens; /* bit lengths of codes */
+ uInt bb; /* bit length tree depth */
+ inflate_huft *tb; /* bit length decoding tree */
+ int nblens; /* # elements allocated at blens */
+ } trees; /* if DTREE, decoding info for trees */
+ struct {
+ inflate_huft *tl, *td; /* trees to free */
+ inflate_codes_statef
+ *codes;
+ } decode; /* if CODES, current state */
+ } sub; /* submode */
+ uInt last; /* true if this block is the last block */
+
+ /* mode independent information */
+ uInt bitk; /* bits in bit buffer */
+ uLong bitb; /* bit buffer */
+ Bytef *window; /* sliding window */
+ Bytef *end; /* one byte after sliding window */
+ Bytef *read; /* window read pointer */
+ Bytef *write; /* window write pointer */
+ check_func checkfn; /* check function */
+ uLong check; /* check on output */
+
+};
+
+
+/* defines for inflate input/output */
+/* update pointers and return */
+#define UPDBITS {s->bitb=b;s->bitk=k;}
+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
+#define UPDOUT {s->write=q;}
+#define UPDATE {UPDBITS UPDIN UPDOUT}
+#define LEAVE {UPDATE return inflate_flush(s,z,r);}
+/* get bytes and bits */
+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
+#define NEXTBYTE (n--,*p++)
+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+#define DUMPBITS(j) {b>>=(j);k-=(j);}
+/* output bytes */
+#define WAVAIL (q<s->read?s->read-q-1:s->end-q)
+#define LOADOUT {q=s->write;m=WAVAIL;}
+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}}
+#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
+/* load local pointers */
+#define LOAD {LOADIN LOADOUT}
+
+/*
+ * The IBM 150 firmware munges the data right after _etext[]. This
+ * protects it. -- Cort
+ */
+local uInt protect_mask[] = {0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 ,0 ,0};
+/* And'ing with mask[n] masks the lower n bits */
+local uInt inflate_mask[] = {
+ 0x0000,
+ 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+ 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+};
+
+/* copy as much as possible from the sliding window to the output area */
+local int inflate_flush OF((
+ inflate_blocks_statef *,
+ z_stream *,
+ int));
+
+/*+++++*/
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+local int inflate_fast OF((
+ uInt,
+ uInt,
+ inflate_huft *,
+ inflate_huft *,
+ inflate_blocks_statef *,
+ z_stream *));
+
+
+/*+++++*/
+/* infblock.c -- interpret and process block types to last block
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* Table for deflate from PKZIP's appnote.txt. */
+local uInt border[] = { /* Order of the bit length code lengths */
+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+/*
+ Notes beyond the 1.93a appnote.txt:
+
+ 1. Distance pointers never point before the beginning of the output
+ stream.
+ 2. Distance pointers can point back across blocks, up to 32k away.
+ 3. There is an implied maximum of 7 bits for the bit length table and
+ 15 bits for the actual data.
+ 4. If only one code exists, then it is encoded using one bit. (Zero
+ would be more efficient, but perhaps a little confusing.) If two
+ codes exist, they are coded using one bit each (0 and 1).
+ 5. There is no way of sending zero distance codes--a dummy must be
+ sent if there are none. (History: a pre 2.0 version of PKZIP would
+ store blocks with no distance codes, but this was discovered to be
+ too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
+ zero distance codes, which is sent as one code of zero bits in
+ length.
+ 6. There are up to 286 literal/length codes. Code 256 represents the
+ end-of-block. Note however that the static length tree defines
+ 288 codes just to fill out the Huffman codes. Codes 286 and 287
+ cannot be used though, since there is no length base or extra bits
+ defined for them. Similarily, there are up to 30 distance codes.
+ However, static trees define 32 codes (all 5 bits) to fill out the
+ Huffman codes, but the last two had better not show up in the data.
+ 7. Unzip can check dynamic Huffman blocks for complete code sets.
+ The exception is that a single code would not be complete (see #4).
+ 8. The five bits following the block type is really the number of
+ literal codes sent minus 257.
+ 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
+ (1+6+6). Therefore, to output three times the length, you output
+ three codes (1+1+1), whereas to output four times the same length,
+ you only need two codes (1+3). Hmm.
+ 10. In the tree reconstruction algorithm, Code = Code + Increment
+ only if BitLength(i) is not zero. (Pretty obvious.)
+ 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
+ 12. Note: length code 284 can represent 227-258, but length code 285
+ really is 258. The last length deserves its own, short code
+ since it gets used a lot in very redundant files. The length
+ 258 is special since 258 - 3 (the min match length) is 255.
+ 13. The literal/length and distance code bit lengths are read as a
+ single stream of lengths. It is possible (and advantageous) for
+ a repeat code (16, 17, or 18) to go across the boundary between
+ the two sets of lengths.
+ */
+
+
+local void inflate_blocks_reset(s, z, c)
+inflate_blocks_statef *s;
+z_stream *z;
+uLongf *c;
+{
+ if (s->checkfn != Z_NULL)
+ *c = s->check;
+ if (s->mode == BTREE || s->mode == DTREE)
+ ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
+ if (s->mode == CODES)
+ {
+ inflate_codes_free(s->sub.decode.codes, z);
+ inflate_trees_free(s->sub.decode.td, z);
+ inflate_trees_free(s->sub.decode.tl, z);
+ }
+ s->mode = TYPE;
+ s->bitk = 0;
+ s->bitb = 0;
+ s->read = s->write = s->window;
+ if (s->checkfn != Z_NULL)
+ s->check = (*s->checkfn)(0L, Z_NULL, 0);
+ Trace((stderr, "inflate: blocks reset\n"));
+}
+
+
+local inflate_blocks_statef *inflate_blocks_new(z, c, w)
+z_stream *z;
+check_func c;
+uInt w;
+{
+ inflate_blocks_statef *s;
+
+ if ((s = (inflate_blocks_statef *)ZALLOC
+ (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
+ return s;
+ if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
+ {
+ ZFREE(z, s, sizeof(struct inflate_blocks_state));
+ return Z_NULL;
+ }
+ s->end = s->window + w;
+ s->checkfn = c;
+ s->mode = TYPE;
+ Trace((stderr, "inflate: blocks allocated\n"));
+ inflate_blocks_reset(s, z, &s->check);
+ return s;
+}
+
+
+local int inflate_blocks(s, z, r)
+inflate_blocks_statef *s;
+z_stream *z;
+int r;
+{
+ uInt t; /* temporary storage */
+ uLong b; /* bit buffer */
+ uInt k; /* bits in bit buffer */
+ Bytef *p; /* input data pointer */
+ uInt n; /* bytes available there */
+ Bytef *q; /* output window write pointer */
+ uInt m; /* bytes to end of window or read pointer */
+
+ /* copy input/output information to locals (UPDATE macro restores) */
+ LOAD
+
+ /* process input based on current state */
+ while (1) switch (s->mode)
+ {
+ case TYPE:
+ NEEDBITS(3)
+ t = (uInt)b & 7;
+ s->last = t & 1;
+ switch (t >> 1)
+ {
+ case 0: /* stored */
+ Trace((stderr, "inflate: stored block%s\n",
+ s->last ? " (last)" : ""));
+ DUMPBITS(3)
+ t = k & 7; /* go to byte boundary */
+ DUMPBITS(t)
+ s->mode = LENS; /* get length of stored block */
+ break;
+ case 1: /* fixed */
+ Trace((stderr, "inflate: fixed codes block%s\n",
+ s->last ? " (last)" : ""));
+ {
+ uInt bl, bd;
+ inflate_huft *tl, *td;
+
+ inflate_trees_fixed(&bl, &bd, &tl, &td);
+ s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
+ if (s->sub.decode.codes == Z_NULL)
+ {
+ r = Z_MEM_ERROR;
+ LEAVE
+ }
+ s->sub.decode.tl = Z_NULL; /* don't try to free these */
+ s->sub.decode.td = Z_NULL;
+ }
+ DUMPBITS(3)
+ s->mode = CODES;
+ break;
+ case 2: /* dynamic */
+ Trace((stderr, "inflate: dynamic codes block%s\n",
+ s->last ? " (last)" : ""));
+ DUMPBITS(3)
+ s->mode = TABLE;
+ break;
+ case 3: /* illegal */
+ DUMPBITS(3)
+ s->mode = BADB;
+ z->msg = "invalid block type";
+ r = Z_DATA_ERROR;
+ LEAVE
+ }
+ break;
+ case LENS:
+ NEEDBITS(32)
+ if (((~b) >> 16) != (b & 0xffff))
+ {
+ s->mode = BADB;
+ z->msg = "invalid stored block lengths";
+ r = Z_DATA_ERROR;
+ LEAVE
+ }
+ s->sub.left = (uInt)b & 0xffff;
+ b = k = 0; /* dump bits */
+ Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
+ s->mode = s->sub.left ? STORED : TYPE;
+ break;
+ case STORED:
+ if (n == 0)
+ LEAVE
+ NEEDOUT
+ t = s->sub.left;
+ if (t > n) t = n;
+ if (t > m) t = m;
+ zmemcpy(q, p, t);
+ p += t; n -= t;
+ q += t; m -= t;
+ if ((s->sub.left -= t) != 0)
+ break;
+ Tracev((stderr, "inflate: stored end, %lu total out\n",
+ z->total_out + (q >= s->read ? q - s->read :
+ (s->end - s->read) + (q - s->window))));
+ s->mode = s->last ? DRY : TYPE;
+ break;
+ case TABLE:
+ NEEDBITS(14)
+ s->sub.trees.table = t = (uInt)b & 0x3fff;
+#ifndef PKZIP_BUG_WORKAROUND
+ if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
+ {
+ s->mode = BADB;
+ z->msg = "too many length or distance symbols";
+ r = Z_DATA_ERROR;
+ LEAVE
+ }
+#endif
+ t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
+ if (t < 19)
+ t = 19;
+ if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
+ {
+ r = Z_MEM_ERROR;
+ LEAVE
+ }
+ s->sub.trees.nblens = t;
+ DUMPBITS(14)
+ s->sub.trees.index = 0;
+ Tracev((stderr, "inflate: table sizes ok\n"));
+ s->mode = BTREE;
+ case BTREE:
+ while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
+ {
+ NEEDBITS(3)
+ s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
+ DUMPBITS(3)
+ }
+ while (s->sub.trees.index < 19)
+ s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
+ s->sub.trees.bb = 7;
+ t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
+ &s->sub.trees.tb, z);
+ if (t != Z_OK)
+ {
+ r = t;
+ if (r == Z_DATA_ERROR)
+ s->mode = BADB;
+ LEAVE
+ }
+ s->sub.trees.index = 0;
+ Tracev((stderr, "inflate: bits tree ok\n"));
+ s->mode = DTREE;
+ case DTREE:
+ while (t = s->sub.trees.table,
+ s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
+ {
+ inflate_huft *h;
+ uInt i, j, c;
+
+ t = s->sub.trees.bb;
+ NEEDBITS(t)
+ h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
+ t = h->word.what.Bits;
+ c = h->more.Base;
+ if (c < 16)
+ {
+ DUMPBITS(t)
+ s->sub.trees.blens[s->sub.trees.index++] = c;
+ }
+ else /* c == 16..18 */
+ {
+ i = c == 18 ? 7 : c - 14;
+ j = c == 18 ? 11 : 3;
+ NEEDBITS(t + i)
+ DUMPBITS(t)
+ j += (uInt)b & inflate_mask[i];
+ DUMPBITS(i)
+ i = s->sub.trees.index;
+ t = s->sub.trees.table;
+ if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
+ (c == 16 && i < 1))
+ {
+ s->mode = BADB;
+ z->msg = "invalid bit length repeat";
+ r = Z_DATA_ERROR;
+ LEAVE
+ }
+ c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
+ do {
+ s->sub.trees.blens[i++] = c;
+ } while (--j);
+ s->sub.trees.index = i;
+ }
+ }
+ inflate_trees_free(s->sub.trees.tb, z);
+ s->sub.trees.tb = Z_NULL;
+ {
+ uInt bl, bd;
+ inflate_huft *tl, *td;
+ inflate_codes_statef *c;
+
+ bl = 9; /* must be <= 9 for lookahead assumptions */
+ bd = 6; /* must be <= 9 for lookahead assumptions */
+ t = s->sub.trees.table;
+ t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
+ s->sub.trees.blens, &bl, &bd, &tl, &td, z);
+ if (t != Z_OK)
+ {
+ if (t == (uInt)Z_DATA_ERROR)
+ s->mode = BADB;
+ r = t;
+ LEAVE
+ }
+ Tracev((stderr, "inflate: trees ok\n"));
+ if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
+ {
+ inflate_trees_free(td, z);
+ inflate_trees_free(tl, z);
+ r = Z_MEM_ERROR;
+ LEAVE
+ }
+ ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
+ s->sub.decode.codes = c;
+ s->sub.decode.tl = tl;
+ s->sub.decode.td = td;
+ }
+ s->mode = CODES;
+ case CODES:
+ UPDATE
+ if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
+ return inflate_flush(s, z, r);
+ r = Z_OK;
+ inflate_codes_free(s->sub.decode.codes, z);
+ inflate_trees_free(s->sub.decode.td, z);
+ inflate_trees_free(s->sub.decode.tl, z);
+ LOAD
+ Tracev((stderr, "inflate: codes end, %lu total out\n",
+ z->total_out + (q >= s->read ? q - s->read :
+ (s->end - s->read) + (q - s->window))));
+ if (!s->last)
+ {
+ s->mode = TYPE;
+ break;
+ }
+ if (k > 7) /* return unused byte, if any */
+ {
+ Assert(k < 16, "inflate_codes grabbed too many bytes")
+ k -= 8;
+ n++;
+ p--; /* can always return one */
+ }
+ s->mode = DRY;
+ case DRY:
+ FLUSH
+ if (s->read != s->write)
+ LEAVE
+ s->mode = DONEB;
+ case DONEB:
+ r = Z_STREAM_END;
+ LEAVE
+ case BADB:
+ r = Z_DATA_ERROR;
+ LEAVE
+ default:
+ r = Z_STREAM_ERROR;
+ LEAVE
+ }
+}
+
+
+local int inflate_blocks_free(s, z, c)
+inflate_blocks_statef *s;
+z_stream *z;
+uLongf *c;
+{
+ inflate_blocks_reset(s, z, c);
+ ZFREE(z, s->window, s->end - s->window);
+ ZFREE(z, s, sizeof(struct inflate_blocks_state));
+ Trace((stderr, "inflate: blocks freed\n"));
+ return Z_OK;
+}
+
+/*
+ * This subroutine adds the data at next_in/avail_in to the output history
+ * without performing any output. The output buffer must be "caught up";
+ * i.e. no pending output (hence s->read equals s->write), and the state must
+ * be BLOCKS (i.e. we should be willing to see the start of a series of
+ * BLOCKS). On exit, the output will also be caught up, and the checksum
+ * will have been updated if need be.
+ */
+local int inflate_addhistory(s, z)
+inflate_blocks_statef *s;
+z_stream *z;
+{
+ uLong b; /* bit buffer */ /* NOT USED HERE */
+ uInt k; /* bits in bit buffer */ /* NOT USED HERE */
+ uInt t; /* temporary storage */
+ Bytef *p; /* input data pointer */
+ uInt n; /* bytes available there */
+ Bytef *q; /* output window write pointer */
+ uInt m; /* bytes to end of window or read pointer */
+
+ if (s->read != s->write)
+ return Z_STREAM_ERROR;
+ if (s->mode != TYPE)
+ return Z_DATA_ERROR;
+
+ /* we're ready to rock */
+ LOAD
+ /* while there is input ready, copy to output buffer, moving
+ * pointers as needed.
+ */
+ while (n) {
+ t = n; /* how many to do */
+ /* is there room until end of buffer? */
+ if (t > m) t = m;
+ /* update check information */
+ if (s->checkfn != Z_NULL)
+ s->check = (*s->checkfn)(s->check, q, t);
+ zmemcpy(q, p, t);
+ q += t;
+ p += t;
+ n -= t;
+ z->total_out += t;
+ s->read = q; /* drag read pointer forward */
+/* WRAP */ /* expand WRAP macro by hand to handle s->read */
+ if (q == s->end) {
+ s->read = q = s->window;
+ m = WAVAIL;
+ }
+ }
+ UPDATE
+ return Z_OK;
+}
+
+
+/*
+ * At the end of a Deflate-compressed PPP packet, we expect to have seen
+ * a `stored' block type value but not the (zero) length bytes.
+ */
+local int inflate_packet_flush(s)
+ inflate_blocks_statef *s;
+{
+ if (s->mode != LENS)
+ return Z_DATA_ERROR;
+ s->mode = TYPE;
+ return Z_OK;
+}
+
+
+/*+++++*/
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define base more.Base
+#define next more.Next
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+
+local int huft_build OF((
+ uIntf *, /* code lengths in bits */
+ uInt, /* number of codes */
+ uInt, /* number of "simple" codes */
+ uIntf *, /* list of base values for non-simple codes */
+ uIntf *, /* list of extra bits for non-simple codes */
+ inflate_huft * FAR*,/* result: starting table */
+ uIntf *, /* maximum lookup bits (returns actual) */
+ z_stream *)); /* for zalloc function */
+
+local voidpf falloc OF((
+ voidpf, /* opaque pointer (not used) */
+ uInt, /* number of items */
+ uInt)); /* size of item */
+
+local void ffree OF((
+ voidpf q, /* opaque pointer (not used) */
+ voidpf p, /* what to free (not used) */
+ uInt n)); /* number of bytes (not used) */
+
+/* Tables for deflate from PKZIP's appnote.txt. */
+local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+ /* actually lengths - 2; also see note #13 above about 258 */
+local uInt cplext[] = { /* Extra bits for literal codes 257..285 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */
+local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+ 8193, 12289, 16385, 24577};
+local uInt cpdext[] = { /* Extra bits for distance codes */
+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+ 12, 12, 13, 13};
+
+/*
+ Huffman code decoding is performed using a multi-level table lookup.
+ The fastest way to decode is to simply build a lookup table whose
+ size is determined by the longest code. However, the time it takes
+ to build this table can also be a factor if the data being decoded
+ is not very long. The most common codes are necessarily the
+ shortest codes, so those codes dominate the decoding time, and hence
+ the speed. The idea is you can have a shorter table that decodes the
+ shorter, more probable codes, and then point to subsidiary tables for
+ the longer codes. The time it costs to decode the longer codes is
+ then traded against the time it takes to make longer tables.
+
+ This results of this trade are in the variables lbits and dbits
+ below. lbits is the number of bits the first level table for literal/
+ length codes can decode in one step, and dbits is the same thing for
+ the distance codes. Subsequent tables are also less than or equal to
+ those sizes. These values may be adjusted either when all of the
+ codes are shorter than that, in which case the longest code length in
+ bits is used, or when the shortest code is *longer* than the requested
+ table size, in which case the length of the shortest code in bits is
+ used.
+
+ There are two different values for the two tables, since they code a
+ different number of possibilities each. The literal/length table
+ codes 286 possible values, or in a flat code, a little over eight
+ bits. The distance table codes 30 possible values, or a little less
+ than five bits, flat. The optimum values for speed end up being
+ about one bit more than those, so lbits is 8+1 and dbits is 5+1.
+ The optimum values may differ though from machine to machine, and
+ possibly even between compilers. Your mileage may vary.
+ */
+
+
+/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
+#define BMAX 15 /* maximum bit length of any code */
+#define N_MAX 288 /* maximum number of codes in any set */
+
+#ifdef DEBUG_ZLIB
+ uInt inflate_hufts;
+#endif
+
+local int huft_build(b, n, s, d, e, t, m, zs)
+uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
+uInt n; /* number of codes (assumed <= N_MAX) */
+uInt s; /* number of simple-valued codes (0..s-1) */
+uIntf *d; /* list of base values for non-simple codes */
+uIntf *e; /* list of extra bits for non-simple codes */
+inflate_huft * FAR *t; /* result: starting table */
+uIntf *m; /* maximum lookup bits, returns actual */
+z_stream *zs; /* for zalloc function */
+/* Given a list of code lengths and a maximum table size, make a set of
+ tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
+ if the given code set is incomplete (the tables are still built in this
+ case), Z_DATA_ERROR if the input is invalid (all zero length codes or an
+ over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */
+{
+
+ uInt a; /* counter for codes of length k */
+ uInt c[BMAX+1]; /* bit length count table */
+ uInt f; /* i repeats in table every f entries */
+ int g; /* maximum code length */
+ int h; /* table level */
+ register uInt i; /* counter, current code */
+ register uInt j; /* counter */
+ register int k; /* number of bits in current code */
+ int l; /* bits per table (returned in m) */
+ register uIntf *p; /* pointer into c[], b[], or v[] */
+ inflate_huft *q; /* points to current table */
+ struct inflate_huft_s r; /* table entry for structure assignment */
+ inflate_huft *u[BMAX]; /* table stack */
+ uInt v[N_MAX]; /* values in order of bit length */
+ register int w; /* bits before this table == (l * h) */
+ uInt x[BMAX+1]; /* bit offsets, then code stack */
+ uIntf *xp; /* pointer into x */
+ int y; /* number of dummy codes added */
+ uInt z; /* number of entries in current table */
+
+
+ /* Generate counts for each bit length */
+ p = c;
+#define C0 *p++ = 0;
+#define C2 C0 C0 C0 C0
+#define C4 C2 C2 C2 C2
+ C4 /* clear c[]--assume BMAX+1 is 16 */
+ p = b; i = n;
+ do {
+ c[*p++]++; /* assume all entries <= BMAX */
+ } while (--i);
+ if (c[0] == n) /* null input--all zero length codes */
+ {
+ *t = (inflate_huft *)Z_NULL;
+ *m = 0;
+ return Z_OK;
+ }
+
+
+ /* Find minimum and maximum length, bound *m by those */
+ l = *m;
+ for (j = 1; j <= BMAX; j++)
+ if (c[j])
+ break;
+ k = j; /* minimum code length */
+ if ((uInt)l < j)
+ l = j;
+ for (i = BMAX; i; i--)
+ if (c[i])
+ break;
+ g = i; /* maximum code length */
+ if ((uInt)l > i)
+ l = i;
+ *m = l;
+
+
+ /* Adjust last length count to fill out codes, if needed */
+ for (y = 1 << j; j < i; j++, y <<= 1)
+ if ((y -= c[j]) < 0)
+ return Z_DATA_ERROR;
+ if ((y -= c[i]) < 0)
+ return Z_DATA_ERROR;
+ c[i] += y;
+
+
+ /* Generate starting offsets into the value table for each length */
+ x[1] = j = 0;
+ p = c + 1; xp = x + 2;
+ while (--i) { /* note that i == g from above */
+ *xp++ = (j += *p++);
+ }
+
+
+ /* Make a table of values in order of bit lengths */
+ p = b; i = 0;
+ do {
+ if ((j = *p++) != 0)
+ v[x[j]++] = i;
+ } while (++i < n);
+
+
+ /* Generate the Huffman codes and for each, make the table entries */
+ x[0] = i = 0; /* first Huffman code is zero */
+ p = v; /* grab values in bit order */
+ h = -1; /* no tables yet--level -1 */
+ w = -l; /* bits decoded == (l * h) */
+ u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
+ q = (inflate_huft *)Z_NULL; /* ditto */
+ z = 0; /* ditto */
+
+ /* go through the bit lengths (k already is bits in shortest code) */
+ for (; k <= g; k++)
+ {
+ a = c[k];
+ while (a--)
+ {
+ /* here i is the Huffman code of length k bits for value *p */
+ /* make tables up to required level */
+ while (k > w + l)
+ {
+ h++;
+ w += l; /* previous table always l bits */
+
+ /* compute minimum size table less than or equal to l bits */
+ z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */
+ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
+ { /* too few codes for k-w bit table */
+ f -= a + 1; /* deduct codes from patterns left */
+ xp = c + k;
+ if (j < z)
+ while (++j < z) /* try smaller tables up to z bits */
+ {
+ if ((f <<= 1) <= *++xp)
+ break; /* enough codes to use up j bits */
+ f -= *xp; /* else deduct codes from patterns */
+ }
+ }
+ z = 1 << j; /* table entries for j-bit table */
+
+ /* allocate and link in new table */
+ if ((q = (inflate_huft *)ZALLOC
+ (zs,z + 1,sizeof(inflate_huft))) == Z_NULL)
+ {
+ if (h)
+ inflate_trees_free(u[0], zs);
+ return Z_MEM_ERROR; /* not enough memory */
+ }
+ q->word.Nalloc = z + 1;
+#ifdef DEBUG_ZLIB
+ inflate_hufts += z + 1;
+#endif
+ *t = q + 1; /* link to list for huft_free() */
+ *(t = &(q->next)) = Z_NULL;
+ u[h] = ++q; /* table starts after link */
+
+ /* connect to last table, if there is one */
+ if (h)
+ {
+ x[h] = i; /* save pattern for backing up */
+ r.bits = (Byte)l; /* bits to dump before this table */
+ r.exop = (Byte)j; /* bits in this table */
+ r.next = q; /* pointer to this table */
+ j = i >> (w - l); /* (get around Turbo C bug) */
+ u[h-1][j] = r; /* connect to last table */
+ }
+ }
+
+ /* set up table entry in r */
+ r.bits = (Byte)(k - w);
+ if (p >= v + n)
+ r.exop = 128 + 64; /* out of values--invalid code */
+ else if (*p < s)
+ {
+ r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
+ r.base = *p++; /* simple code is just the value */
+ }
+ else
+ {
+ r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */
+ r.base = d[*p++ - s];
+ }
+
+ /* fill code-like entries with r */
+ f = 1 << (k - w);
+ for (j = i >> w; j < z; j += f)
+ q[j] = r;
+
+ /* backwards increment the k-bit code i */
+ for (j = 1 << (k - 1); i & j; j >>= 1)
+ i ^= j;
+ i ^= j;
+
+ /* backup over finished tables */
+ while ((i & ((1 << w) - 1)) != x[h])
+ {
+ h--; /* don't need to update q */
+ w -= l;
+ }
+ }
+ }
+
+
+ /* Return Z_BUF_ERROR if we were given an incomplete table */
+ return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
+}
+
+
+local int inflate_trees_bits(c, bb, tb, z)
+uIntf *c; /* 19 code lengths */
+uIntf *bb; /* bits tree desired/actual depth */
+inflate_huft * FAR *tb; /* bits tree result */
+z_stream *z; /* for zfree function */
+{
+ int r;
+
+ r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z);
+ if (r == Z_DATA_ERROR)
+ z->msg = "oversubscribed dynamic bit lengths tree";
+ else if (r == Z_BUF_ERROR)
+ {
+ inflate_trees_free(*tb, z);
+ z->msg = "incomplete dynamic bit lengths tree";
+ r = Z_DATA_ERROR;
+ }
+ return r;
+}
+
+
+local int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z)
+uInt nl; /* number of literal/length codes */
+uInt nd; /* number of distance codes */
+uIntf *c; /* that many (total) code lengths */
+uIntf *bl; /* literal desired/actual bit depth */
+uIntf *bd; /* distance desired/actual bit depth */
+inflate_huft * FAR *tl; /* literal/length tree result */
+inflate_huft * FAR *td; /* distance tree result */
+z_stream *z; /* for zfree function */
+{
+ int r;
+
+ /* build literal/length tree */
+ if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK)
+ {
+ if (r == Z_DATA_ERROR)
+ z->msg = "oversubscribed literal/length tree";
+ else if (r == Z_BUF_ERROR)
+ {
+ inflate_trees_free(*tl, z);
+ z->msg = "incomplete literal/length tree";
+ r = Z_DATA_ERROR;
+ }
+ return r;
+ }
+
+ /* build distance tree */
+ if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK)
+ {
+ if (r == Z_DATA_ERROR)
+ z->msg = "oversubscribed literal/length tree";
+ else if (r == Z_BUF_ERROR) {
+#ifdef PKZIP_BUG_WORKAROUND
+ r = Z_OK;
+ }
+#else
+ inflate_trees_free(*td, z);
+ z->msg = "incomplete literal/length tree";
+ r = Z_DATA_ERROR;
+ }
+ inflate_trees_free(*tl, z);
+ return r;
+#endif
+ }
+
+ /* done */
+ return Z_OK;
+}
+
+
+/* build fixed tables only once--keep them here */
+local int fixed_lock = 0;
+local int fixed_built = 0;
+#define FIXEDH 530 /* number of hufts used by fixed tables */
+local uInt fixed_left = FIXEDH;
+local inflate_huft fixed_mem[FIXEDH];
+local uInt fixed_bl;
+local uInt fixed_bd;
+local inflate_huft *fixed_tl;
+local inflate_huft *fixed_td;
+
+
+local voidpf falloc(q, n, s)
+voidpf q; /* opaque pointer (not used) */
+uInt n; /* number of items */
+uInt s; /* size of item */
+{
+ Assert(s == sizeof(inflate_huft) && n <= fixed_left,
+ "inflate_trees falloc overflow");
+ if (q) s++; /* to make some compilers happy */
+ fixed_left -= n;
+ return (voidpf)(fixed_mem + fixed_left);
+}
+
+
+local void ffree(q, p, n)
+voidpf q;
+voidpf p;
+uInt n;
+{
+ Assert(0, "inflate_trees ffree called!");
+ if (q) q = p; /* to make some compilers happy */
+}
+
+
+local int inflate_trees_fixed(bl, bd, tl, td)
+uIntf *bl; /* literal desired/actual bit depth */
+uIntf *bd; /* distance desired/actual bit depth */
+inflate_huft * FAR *tl; /* literal/length tree result */
+inflate_huft * FAR *td; /* distance tree result */
+{
+ /* build fixed tables if not built already--lock out other instances */
+ while (++fixed_lock > 1)
+ fixed_lock--;
+ if (!fixed_built)
+ {
+ int k; /* temporary variable */
+ unsigned c[288]; /* length list for huft_build */
+ z_stream z; /* for falloc function */
+
+ /* set up fake z_stream for memory routines */
+ z.zalloc = falloc;
+ z.zfree = ffree;
+ z.opaque = Z_NULL;
+
+ /* literal table */
+ for (k = 0; k < 144; k++)
+ c[k] = 8;
+ for (; k < 256; k++)
+ c[k] = 9;
+ for (; k < 280; k++)
+ c[k] = 7;
+ for (; k < 288; k++)
+ c[k] = 8;
+ fixed_bl = 7;
+ huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z);
+
+ /* distance table */
+ for (k = 0; k < 30; k++)
+ c[k] = 5;
+ fixed_bd = 5;
+ huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z);
+
+ /* done */
+ fixed_built = 1;
+ }
+ fixed_lock--;
+ *bl = fixed_bl;
+ *bd = fixed_bd;
+ *tl = fixed_tl;
+ *td = fixed_td;
+ return Z_OK;
+}
+
+
+local int inflate_trees_free(t, z)
+inflate_huft *t; /* table to free */
+z_stream *z; /* for zfree function */
+/* Free the malloc'ed tables built by huft_build(), which makes a linked
+ list of the tables it made, with the links in a dummy first entry of
+ each table. */
+{
+ register inflate_huft *p, *q;
+
+ /* Go through linked list, freeing from the malloced (t[-1]) address. */
+ p = t;
+ while (p != Z_NULL)
+ {
+ q = (--p)->next;
+ ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft));
+ p = q;
+ }
+ return Z_OK;
+}
+
+/*+++++*/
+/* infcodes.c -- process literals and length/distance pairs
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define base more.Base
+#define next more.Next
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* inflate codes private state */
+struct inflate_codes_state {
+
+ /* mode */
+ enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+ START, /* x: set up for LEN */
+ LEN, /* i: get length/literal/eob next */
+ LENEXT, /* i: getting length extra (have base) */
+ DIST, /* i: get distance next */
+ DISTEXT, /* i: getting distance extra */
+ COPY, /* o: copying bytes in window, waiting for space */
+ LIT, /* o: got literal, waiting for output space */
+ WASH, /* o: got eob, possibly still output waiting */
+ END, /* x: got eob and all data flushed */
+ BADCODE} /* x: got error */
+ mode; /* current inflate_codes mode */
+
+ /* mode dependent information */
+ uInt len;
+ union {
+ struct {
+ inflate_huft *tree; /* pointer into tree */
+ uInt need; /* bits needed */
+ } code; /* if LEN or DIST, where in tree */
+ uInt lit; /* if LIT, literal */
+ struct {
+ uInt get; /* bits to get for extra */
+ uInt dist; /* distance back to copy from */
+ } copy; /* if EXT or COPY, where and how much */
+ } sub; /* submode */
+
+ /* mode independent information */
+ Byte lbits; /* ltree bits decoded per branch */
+ Byte dbits; /* dtree bits decoder per branch */
+ inflate_huft *ltree; /* literal/length/eob tree */
+ inflate_huft *dtree; /* distance tree */
+
+};
+
+
+local inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
+uInt bl, bd;
+inflate_huft *tl, *td;
+z_stream *z;
+{
+ inflate_codes_statef *c;
+
+ if ((c = (inflate_codes_statef *)
+ ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
+ {
+ c->mode = START;
+ c->lbits = (Byte)bl;
+ c->dbits = (Byte)bd;
+ c->ltree = tl;
+ c->dtree = td;
+ Tracev((stderr, "inflate: codes new\n"));
+ }
+ return c;
+}
+
+
+local int inflate_codes(s, z, r)
+inflate_blocks_statef *s;
+z_stream *z;
+int r;
+{
+ uInt j; /* temporary storage */
+ inflate_huft *t; /* temporary pointer */
+ uInt e; /* extra bits or operation */
+ uLong b; /* bit buffer */
+ uInt k; /* bits in bit buffer */
+ Bytef *p; /* input data pointer */
+ uInt n; /* bytes available there */
+ Bytef *q; /* output window write pointer */
+ uInt m; /* bytes to end of window or read pointer */
+ Bytef *f; /* pointer to copy strings from */
+ inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
+
+ /* copy input/output information to locals (UPDATE macro restores) */
+ LOAD
+
+ /* process input and output based on current state */
+ while (1) switch (c->mode)
+ { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+ case START: /* x: set up for LEN */
+#ifndef SLOW
+ if (m >= 258 && n >= 10)
+ {
+ UPDATE
+ r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
+ LOAD
+ if (r != Z_OK)
+ {
+ c->mode = r == Z_STREAM_END ? WASH : BADCODE;
+ break;
+ }
+ }
+#endif /* !SLOW */
+ c->sub.code.need = c->lbits;
+ c->sub.code.tree = c->ltree;
+ c->mode = LEN;
+ case LEN: /* i: get length/literal/eob next */
+ j = c->sub.code.need;
+ NEEDBITS(j)
+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+ DUMPBITS(t->bits)
+ e = (uInt)(t->exop);
+ if (e == 0) /* literal */
+ {
+ c->sub.lit = t->base;
+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", t->base));
+ c->mode = LIT;
+ break;
+ }
+ if (e & 16) /* length */
+ {
+ c->sub.copy.get = e & 15;
+ c->len = t->base;
+ c->mode = LENEXT;
+ break;
+ }
+ if ((e & 64) == 0) /* next table */
+ {
+ c->sub.code.need = e;
+ c->sub.code.tree = t->next;
+ break;
+ }
+ if (e & 32) /* end of block */
+ {
+ Tracevv((stderr, "inflate: end of block\n"));
+ c->mode = WASH;
+ break;
+ }
+ c->mode = BADCODE; /* invalid code */
+ z->msg = "invalid literal/length code";
+ r = Z_DATA_ERROR;
+ LEAVE
+ case LENEXT: /* i: getting length extra (have base) */
+ j = c->sub.copy.get;
+ NEEDBITS(j)
+ c->len += (uInt)b & inflate_mask[j];
+ DUMPBITS(j)
+ c->sub.code.need = c->dbits;
+ c->sub.code.tree = c->dtree;
+ Tracevv((stderr, "inflate: length %u\n", c->len));
+ c->mode = DIST;
+ case DIST: /* i: get distance next */
+ j = c->sub.code.need;
+ NEEDBITS(j)
+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+ DUMPBITS(t->bits)
+ e = (uInt)(t->exop);
+ if (e & 16) /* distance */
+ {
+ c->sub.copy.get = e & 15;
+ c->sub.copy.dist = t->base;
+ c->mode = DISTEXT;
+ break;
+ }
+ if ((e & 64) == 0) /* next table */
+ {
+ c->sub.code.need = e;
+ c->sub.code.tree = t->next;
+ break;
+ }
+ c->mode = BADCODE; /* invalid code */
+ z->msg = "invalid distance code";
+ r = Z_DATA_ERROR;
+ LEAVE
+ case DISTEXT: /* i: getting distance extra */
+ j = c->sub.copy.get;
+ NEEDBITS(j)
+ c->sub.copy.dist += (uInt)b & inflate_mask[j];
+ DUMPBITS(j)
+ Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
+ c->mode = COPY;
+ case COPY: /* o: copying bytes in window, waiting for space */
+#ifndef __TURBOC__ /* Turbo C bug for following expression */
+ f = (uInt)(q - s->window) < c->sub.copy.dist ?
+ s->end - (c->sub.copy.dist - (q - s->window)) :
+ q - c->sub.copy.dist;
+#else
+ f = q - c->sub.copy.dist;
+ if ((uInt)(q - s->window) < c->sub.copy.dist)
+ f = s->end - (c->sub.copy.dist - (q - s->window));
+#endif
+ while (c->len)
+ {
+ NEEDOUT
+ OUTBYTE(*f++)
+ if (f == s->end)
+ f = s->window;
+ c->len--;
+ }
+ c->mode = START;
+ break;
+ case LIT: /* o: got literal, waiting for output space */
+ NEEDOUT
+ OUTBYTE(c->sub.lit)
+ c->mode = START;
+ break;
+ case WASH: /* o: got eob, possibly more output */
+ FLUSH
+ if (s->read != s->write)
+ LEAVE
+ c->mode = END;
+ case END:
+ r = Z_STREAM_END;
+ LEAVE
+ case BADCODE: /* x: got error */
+ r = Z_DATA_ERROR;
+ LEAVE
+ default:
+ r = Z_STREAM_ERROR;
+ LEAVE
+ }
+}
+
+
+local void inflate_codes_free(c, z)
+inflate_codes_statef *c;
+z_stream *z;
+{
+ ZFREE(z, c, sizeof(struct inflate_codes_state));
+ Tracev((stderr, "inflate: codes free\n"));
+}
+
+/*+++++*/
+/* inflate_util.c -- data and routines common to blocks and codes
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* copy as much as possible from the sliding window to the output area */
+local int inflate_flush(s, z, r)
+inflate_blocks_statef *s;
+z_stream *z;
+int r;
+{
+ uInt n;
+ Bytef *p, *q;
+
+ /* local copies of source and destination pointers */
+ p = z->next_out;
+ q = s->read;
+
+ /* compute number of bytes to copy as far as end of window */
+ n = (uInt)((q <= s->write ? s->write : s->end) - q);
+ if (n > z->avail_out) n = z->avail_out;
+ if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+ /* update counters */
+ z->avail_out -= n;
+ z->total_out += n;
+
+ /* update check information */
+ if (s->checkfn != Z_NULL)
+ s->check = (*s->checkfn)(s->check, q, n);
+
+ /* copy as far as end of window */
+ zmemcpy(p, q, n);
+ p += n;
+ q += n;
+
+ /* see if more to copy at beginning of window */
+ if (q == s->end)
+ {
+ /* wrap pointers */
+ q = s->window;
+ if (s->write == s->end)
+ s->write = s->window;
+
+ /* compute bytes to copy */
+ n = (uInt)(s->write - q);
+ if (n > z->avail_out) n = z->avail_out;
+ if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+ /* update counters */
+ z->avail_out -= n;
+ z->total_out += n;
+
+ /* update check information */
+ if (s->checkfn != Z_NULL)
+ s->check = (*s->checkfn)(s->check, q, n);
+
+ /* copy */
+ zmemcpy(p, q, n);
+ p += n;
+ q += n;
+ }
+
+ /* update pointers */
+ z->next_out = p;
+ s->read = q;
+
+ /* done */
+ return r;
+}
+
+
+/*+++++*/
+/* inffast.c -- process literals and length/distance pairs fast
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define base more.Base
+#define next more.Next
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* macros for bit input with no checking and for returning unused bytes */
+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+#define UNGRAB {n+=(c=k>>3);p-=c;k&=7;}
+
+/* Called with number of bytes left to write in window at least 258
+ (the maximum string length) and number of input bytes available
+ at least ten. The ten bytes are six bytes for the longest length/
+ distance pair plus four bytes for overloading the bit buffer. */
+
+local int inflate_fast(bl, bd, tl, td, s, z)
+uInt bl, bd;
+inflate_huft *tl, *td;
+inflate_blocks_statef *s;
+z_stream *z;
+{
+ inflate_huft *t; /* temporary pointer */
+ uInt e; /* extra bits or operation */
+ uLong b; /* bit buffer */
+ uInt k; /* bits in bit buffer */
+ Bytef *p; /* input data pointer */
+ uInt n; /* bytes available there */
+ Bytef *q; /* output window write pointer */
+ uInt m; /* bytes to end of window or read pointer */
+ uInt ml; /* mask for literal/length tree */
+ uInt md; /* mask for distance tree */
+ uInt c; /* bytes to copy */
+ uInt d; /* distance back to copy from */
+ Bytef *r; /* copy source pointer */
+
+ /* load input, output, bit values */
+ LOAD
+
+ /* initialize masks */
+ ml = inflate_mask[bl];
+ md = inflate_mask[bd];
+
+ /* do until not enough input or output space for fast loop */
+ do { /* assume called with m >= 258 && n >= 10 */
+ /* get literal/length code */
+ GRABBITS(20) /* max bits for literal/length code */
+ if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
+ {
+ DUMPBITS(t->bits)
+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+ "inflate: * literal '%c'\n" :
+ "inflate: * literal 0x%02x\n", t->base));
+ *q++ = (Byte)t->base;
+ m--;
+ continue;
+ }
+ do {
+ DUMPBITS(t->bits)
+ if (e & 16)
+ {
+ /* get extra bits for length */
+ e &= 15;
+ c = t->base + ((uInt)b & inflate_mask[e]);
+ DUMPBITS(e)
+ Tracevv((stderr, "inflate: * length %u\n", c));
+
+ /* decode distance base of block to copy */
+ GRABBITS(15); /* max bits for distance code */
+ e = (t = td + ((uInt)b & md))->exop;
+ do {
+ DUMPBITS(t->bits)
+ if (e & 16)
+ {
+ /* get extra bits to add to distance base */
+ e &= 15;
+ GRABBITS(e) /* get extra bits (up to 13) */
+ d = t->base + ((uInt)b & inflate_mask[e]);
+ DUMPBITS(e)
+ Tracevv((stderr, "inflate: * distance %u\n", d));
+
+ /* do the copy */
+ m -= c;
+ if ((uInt)(q - s->window) >= d) /* offset before dest */
+ { /* just copy */
+ r = q - d;
+ *q++ = *r++; c--; /* minimum count is three, */
+ *q++ = *r++; c--; /* so unroll loop a little */
+ }
+ else /* else offset after destination */
+ {
+ e = d - (q - s->window); /* bytes from offset to end */
+ r = s->end - e; /* pointer to offset */
+ if (c > e) /* if source crosses, */
+ {
+ c -= e; /* copy to end of window */
+ do {
+ *q++ = *r++;
+ } while (--e);
+ r = s->window; /* copy rest from start of window */
+ }
+ }
+ do { /* copy all or what's left */
+ *q++ = *r++;
+ } while (--c);
+ break;
+ }
+ else if ((e & 64) == 0)
+ e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop;
+ else
+ {
+ z->msg = "invalid distance code";
+ UNGRAB
+ UPDATE
+ return Z_DATA_ERROR;
+ }
+ } while (1);
+ break;
+ }
+ if ((e & 64) == 0)
+ {
+ if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0)
+ {
+ DUMPBITS(t->bits)
+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+ "inflate: * literal '%c'\n" :
+ "inflate: * literal 0x%02x\n", t->base));
+ *q++ = (Byte)t->base;
+ m--;
+ break;
+ }
+ }
+ else if (e & 32)
+ {
+ Tracevv((stderr, "inflate: * end of block\n"));
+ UNGRAB
+ UPDATE
+ return Z_STREAM_END;
+ }
+ else
+ {
+ z->msg = "invalid literal/length code";
+ UNGRAB
+ UPDATE
+ return Z_DATA_ERROR;
+ }
+ } while (1);
+ } while (m >= 258 && n >= 10);
+
+ /* not enough input or output--restore pointers and return */
+ UNGRAB
+ UPDATE
+ return Z_OK;
+}
+
+
+/*+++++*/
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */
+
+char *zlib_version = ZLIB_VERSION;
+
+char *z_errmsg[] = {
+"stream end", /* Z_STREAM_END 1 */
+"", /* Z_OK 0 */
+"file error", /* Z_ERRNO (-1) */
+"stream error", /* Z_STREAM_ERROR (-2) */
+"data error", /* Z_DATA_ERROR (-3) */
+"insufficient memory", /* Z_MEM_ERROR (-4) */
+"buffer error", /* Z_BUF_ERROR (-5) */
+""};
+
+
+/*+++++*/
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */
+
+#define BASE 65521L /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf) {s1 += *buf++; s2 += s1;}
+#define DO2(buf) DO1(buf); DO1(buf);
+#define DO4(buf) DO2(buf); DO2(buf);
+#define DO8(buf) DO4(buf); DO4(buf);
+#define DO16(buf) DO8(buf); DO8(buf);
+
+/* ========================================================================= */
+uLong adler32(adler, buf, len)
+ uLong adler;
+ Bytef *buf;
+ uInt len;
+{
+ unsigned long s1 = adler & 0xffff;
+ unsigned long s2 = (adler >> 16) & 0xffff;
+ int k;
+
+ if (buf == Z_NULL) return 1L;
+
+ while (len > 0) {
+ k = len < NMAX ? len : NMAX;
+ len -= k;
+ while (k >= 16) {
+ DO16(buf);
+ k -= 16;
+ }
+ if (k != 0) do {
+ DO1(buf);
+ } while (--k);
+ s1 %= BASE;
+ s2 %= BASE;
+ }
+ return (s2 << 16) | s1;
+}
--- /dev/null
+# BK Id: SCCS/s.Makefile 1.5 05/18/01 06:20:29 patch
+#
+#
+# arch/ppc/mbxboot/Makefile
+#
+# 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) 1994 by Linus Torvalds
+# Adapted for PowerPC by Gary Thomas
+# modified by Cort (cort@cs.nmt.edu)
+#
+.c.s:
+ $(CC) $(CFLAGS) -S -o $*.s $<
+.s.o:
+ $(AS) -o $*.o $<
+.c.o:
+ $(CC) $(CFLAGS) -c -o $*.o $<
+.S.s:
+ $(CPP) $(AFLAGS) -traditional -o $*.o $<
+.S.o:
+ $(CC) $(AFLAGS) -traditional -c -o $*.o $<
+
+TFTPIMAGE := /tftpboot/zImage.embedded
+
+OFFSET := ../utils/offset
+SIZE := ../utils/size
+
+LIBS := ../lib/zlib.a
+OBJCOPY_ARGS := -O elf32-powerpc
+
+ifdef CONFIG_8xx
+ZLINKFLAGS := -T $(TOPDIR)/arch/$(ARCH)/vmlinux.lds -Ttext 0x00180000
+OBJECTS := head.o m8xx_tty.o
+CFLAGS += -DCONFIG_8xx
+endif
+
+ifdef CONFIG_8260
+ZLINKFLAGS := -T $(TOPDIR)/arch/$(ARCH)/vmlinux.lds -Ttext 0x00400000
+OBJECTS := head_8260.o m8260_tty.o embed_config.o
+CFLAGS += -DCONFIG_8260
+endif
+
+OBJECTS += ../common/misc-common.o misc.o ../common/string.o
+OBJCOPY_ARGS = -O elf32-powerpc
+
+ifeq ($(CONFIG_MBX),y)
+OBJECTS += iic.o embed_config.o pci.o qspan_pci.o
+CFLAGS += -DCONFIG_MBX
+endif
+ifeq ($(CONFIG_RPXLITE),y)
+CFLAGS += -DCONFIG_RPXLITE
+OBJECTS += iic.o embed_config.o
+endif
+ifeq ($(CONFIG_RPXCLASSIC),y)
+CFLAGS += -DCONFIG_RPXCLASSIC
+OBJECTS += iic.o embed_config.o pci.o qspan_pci.o
+endif
+ifeq ($(CONFIG_BSEIP),y)
+CFLAGS += -DCONFIG_BSEIP
+OBJECTS += iic.o embed_config.o
+endif
+ifeq ($(CONFIG_FADS),y)
+CFLAGS += -DCONFIG_FADS
+OBJECTS += embed_config.o
+endif
+
+all: zImage
+
+misc.o: misc.c
+ $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \
+ -DZIMAGE_SIZE=0 -c -o $@ $*.c
+
+zvmlinux.initrd: $(OBJECTS) $(LIBS) ../images/vmlinux.gz
+ $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS)
+ $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
+ --add-section=initrd=../images/ramdisk.image.gz \
+ --add-section=image=../images/vmlinux.gz \
+ $@.tmp $@
+ $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ initrd` \
+ -DINITRD_SIZE=`sh $(SIZE) $(OBJDUMP) $@ initrd` \
+ -DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ image` \
+ -DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) $@ image` \
+ -c -o misc.o misc.c
+ $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS)
+ $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
+ --add-section=initrd=../images/ramdisk.image.gz \
+ --add-section=image=../images/vmlinux.gz \
+ $@.tmp ../images/$@.mbx
+
+zImage: zvmlinux
+ ln -sf zvmlinux.mbx ../images/zImage.mbx
+
+zImage.initrd: zvmlinux.initrd
+ ln -sf zvmlinux.initrd.mbx ../images/zImage.initrd.mbx
+
+zvmlinux: $(OBJECTS) $(LIBS) ../images/vmlinux.gz
+#
+# build the boot loader image and then compute the offset into it
+# for the kernel image
+#
+ $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS)
+ $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
+ --add-section=image=../images/vmlinux.gz \
+ $@.tmp $@
+#
+# then with the offset rebuild the bootloader so we know where the kernel is
+#
+ $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \
+ -DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ image` \
+ -DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) $@ image` \
+ -c -o misc.o misc.c
+ $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS)
+ $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
+ --add-section=image=../images/vmlinux.gz \
+ $@.tmp ../images/$@.mbx
+# Remove zvmlinux and zvmlinux.temp, we have ../images/zvmlinux.mbx
+ rm -f $@.tmp $@
+
+znetboot : zImage
+ cp ../images/zImage.mbx $(TFTPIMAGE)
+
+znetboot.initrd : zImage.initrd
+ cp ../images/zImage.initrd.mbx $(TFTPIMAGE)
+
+include $(TOPDIR)/Rules.make
--- /dev/null
+/*
+ * BK Id: SCCS/s.embed_config.c 1.7 05/18/01 07:54:04 patch
+ */
+
+/* Board specific functions for those embedded 8xx boards that do
+ * not have boot monitor support for board information.
+ */
+#include <linux/types.h>
+#include <linux/config.h>
+#ifdef CONFIG_8xx
+#include <asm/mpc8xx.h>
+#endif
+#ifdef CONFIG_8260
+#include <asm/mpc8260.h>
+#include <asm/immap_8260.h>
+#endif
+
+
+/* IIC functions.
+ * These are just the basic master read/write operations so we can
+ * examine serial EEPROM.
+ */
+extern void iic_read(uint devaddr, u_char *buf, uint offset, uint count);
+static u_char aschex_to_byte(u_char *cp);
+
+/* Supply a default Ethernet address for those eval boards that don't
+ * ship with one. This is an address from the MBX board I have, so
+ * it is unlikely you will find it on your network.
+ */
+static ushort def_enet_addr[] = { 0x0800, 0x3e26, 0x1559 };
+
+#if defined(CONFIG_MBX)
+
+/* The MBX hands us a pretty much ready to go board descriptor. This
+ * is where the idea started in the first place.
+ */
+void
+embed_config(bd_t *bd)
+{
+ u_char *mp;
+ u_char eebuf[128];
+ int i;
+
+ /* Read the first 128 bytes of the EEPROM. There is more,
+ * but this is all we need.
+ */
+ iic_read(0xa4, eebuf, 0, 128);
+
+ /* All we are looking for is the Ethernet MAC address. The
+ * first 8 bytes are 'MOTOROLA', so check for part of that.
+ * If it's there, assume we have a valid MAC address. If not,
+ * grab our default one.
+ */
+ if ((*(uint *)eebuf) == 0x4d4f544f)
+ mp = &eebuf[0x4c];
+ else
+ mp = (u_char *)def_enet_addr;
+
+ for (i=0; i<6; i++) {
+ bd->bi_enetaddr[i] = *mp++;
+ }
+
+ /* The boot rom passes these to us in MHz. Linux now expects
+ * them to be in Hz.
+ */
+ bd->bi_intfreq *= 1000000;
+ bd->bi_busfreq *= 1000000;
+
+ /* Stuff a baud rate here as well.
+ */
+ bd->bi_baudrate = 9600;
+}
+#endif /* CONFIG_MBX */
+
+#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPX6)
+
+/* Helper functions for Embedded Planet boards.
+*/
+static void
+rpx_eth(bd_t *bd, u_char *cp)
+{
+ int i;
+
+ for (i=0; i<6; i++) {
+ bd->bi_enetaddr[i] = aschex_to_byte(cp);
+ cp += 2;
+ }
+}
+
+static uint
+rpx_baseten(u_char *cp)
+{
+ uint retval;
+
+ retval = 0;
+
+ while (*cp != '\n') {
+ retval *= 10;
+ retval += (*cp) - '0';
+ cp++;
+ }
+ return(retval);
+}
+
+static void
+rpx_brate(bd_t *bd, u_char *cp)
+{
+ uint rate;
+
+ rate = 0;
+
+ while (*cp != '\n') {
+ rate *= 10;
+ rate += (*cp) - '0';
+ cp++;
+ }
+
+ bd->bi_baudrate = rate * 100;
+}
+
+static void
+rpx_memsize(bd_t *bd, u_char *cp)
+{
+ uint size;
+
+ size = 0;
+
+ while (*cp != '\n') {
+ size *= 10;
+ size += (*cp) - '0';
+ cp++;
+ }
+
+ bd->bi_memsize = size * 1024 * 1024;
+}
+
+static void
+rpx_cpuspeed(bd_t *bd, u_char *cp)
+{
+ uint num, den;
+
+ num = den = 0;
+
+ while (*cp != '\n') {
+ num *= 10;
+ num += (*cp) - '0';
+ cp++;
+ if (*cp == '/') {
+ cp++;
+ den = (*cp) - '0';
+ break;
+ }
+ }
+
+ /* I don't know why the RPX just can't state the actual
+ * CPU speed.....
+ */
+ if (den) {
+ num /= den;
+ num *= den;
+ }
+ bd->bi_intfreq = bd->bi_busfreq = num * 1000000;
+
+ /* The 8xx can only run a maximum 50 MHz bus speed (until
+ * Motorola changes this :-). Greater than 50 MHz parts
+ * run internal/2 for bus speed.
+ */
+ if (num > 50)
+ bd->bi_busfreq /= 2;
+}
+
+/* Because I didn't find anything that would do this.......
+*/
+u_char
+aschex_to_byte(u_char *cp)
+{
+ u_char byte, c;
+
+ c = *cp++;
+
+ if ((c >= 'A') && (c <= 'F')) {
+ c -= 'A';
+ c += 10;
+ }
+ else if ((c >= 'a') && (c <= 'f')) {
+ c -= 'a';
+ c += 10;
+ }
+ else {
+ c -= '0';
+ }
+
+ byte = c * 16;
+
+ c = *cp;
+
+ if ((c >= 'A') && (c <= 'F')) {
+ c -= 'A';
+ c += 10;
+ }
+ else if ((c >= 'a') && (c <= 'f')) {
+ c -= 'a';
+ c += 10;
+ }
+ else {
+ c -= '0';
+ }
+
+ byte += c;
+
+ return(byte);
+}
+#endif
+
+#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
+
+/* Read the EEPROM on the RPX-Lite board.
+*/
+void
+embed_config(bd_t *bd)
+{
+ u_char eebuf[256], *cp;
+
+ /* Read the first 256 bytes of the EEPROM. I think this
+ * is really all there is, and I hope if it gets bigger the
+ * info we want is still up front.
+ */
+#if 1
+ iic_read(0xa8, eebuf, 0, 128);
+ iic_read(0xa8, &eebuf[128], 128, 128);
+
+ /* We look for two things, the Ethernet address and the
+ * serial baud rate. The records are separated by
+ * newlines.
+ */
+ cp = eebuf;
+ for (;;) {
+ if (*cp == 'E') {
+ cp++;
+ if (*cp == 'A') {
+ cp += 2;
+ rpx_eth(bd, cp);
+ }
+ }
+ if (*cp == 'S') {
+ cp++;
+ if (*cp == 'B') {
+ cp += 2;
+ rpx_brate(bd, cp);
+ }
+ }
+ if (*cp == 'D') {
+ cp++;
+ if (*cp == '1') {
+ cp += 2;
+ rpx_memsize(bd, cp);
+ }
+ }
+ if (*cp == 'H') {
+ cp++;
+ if (*cp == 'Z') {
+ cp += 2;
+ rpx_cpuspeed(bd, cp);
+ }
+ }
+
+ /* Scan to the end of the record.
+ */
+ while ((*cp != '\n') && (*cp != 0xff))
+ cp++;
+
+ /* If the next character is a 0 or ff, we are done.
+ */
+ cp++;
+ if ((*cp == 0) || (*cp == 0xff))
+ break;
+ }
+ bd->bi_memstart = 0;
+#else
+ /* For boards without initialized EEPROM.
+ */
+ bd->bi_memstart = 0;
+ bd->bi_memsize = (8 * 1024 * 1024);
+ bd->bi_intfreq = 48000000;
+ bd->bi_busfreq = 48000000;
+ bd->bi_baudrate = 9600;
+#endif
+}
+#endif /* RPXLITE || RPXCLASSIC */
+
+#ifdef CONFIG_BSEIP
+/* Build a board information structure for the BSE ip-Engine.
+ * There is more to come since we will add some environment
+ * variables and a function to read them.
+ */
+void
+embed_config(bd_t *bd)
+{
+ u_char *cp;
+ int i;
+
+ /* Baud rate and processor speed will eventually come
+ * from the environment variables.
+ */
+ bd->bi_baudrate = 9600;
+
+ /* Get the Ethernet station address from the Flash ROM.
+ */
+ cp = (u_char *)0xfe003ffa;
+ for (i=0; i<6; i++) {
+ bd->bi_enetaddr[i] = *cp++;
+ }
+
+ /* The rest of this should come from the environment as well.
+ */
+ bd->bi_memstart = 0;
+ bd->bi_memsize = (16 * 1024 * 1024);
+ bd->bi_intfreq = 48000000;
+ bd->bi_busfreq = 48000000;
+}
+#endif /* BSEIP */
+
+#ifdef CONFIG_FADS
+/* Build a board information structure for the FADS.
+ */
+void
+embed_config(bd_t *bd)
+{
+ u_char *cp;
+ int i;
+
+ /* Just fill in some known values.
+ */
+ bd->bi_baudrate = 9600;
+
+ /* Use default enet.
+ */
+ cp = (u_char *)def_enet_addr;
+ for (i=0; i<6; i++) {
+ bd->bi_enetaddr[i] = *cp++;
+ }
+
+ bd->bi_memstart = 0;
+ bd->bi_memsize = (8 * 1024 * 1024);
+ bd->bi_intfreq = 40000000;
+ bd->bi_busfreq = 40000000;
+}
+#endif /* FADS */
+
+#ifdef CONFIG_8260
+/* Compute 8260 clock values if the rom doesn't provide them.
+ * We can't compute the internal core frequency (I don't know how to
+ * do that).
+ */
+static void
+clk_8260(bd_t *bd)
+{
+ uint scmr, vco_out, clkin;
+ uint plldf, pllmf, busdf, brgdf, cpmdf;
+ volatile immap_t *ip;
+
+ ip = (immap_t *)IMAP_ADDR;
+ scmr = ip->im_clkrst.car_scmr;
+
+ /* The clkin is always bus frequency.
+ */
+ clkin = bd->bi_busfreq;
+
+ /* Collect the bits from the scmr.
+ */
+ plldf = (scmr >> 12) & 1;
+ pllmf = scmr & 0xfff;
+ cpmdf = (scmr >> 16) & 0x0f;
+ busdf = (scmr >> 20) & 0x0f;
+
+ /* This is arithmetic from the 8260 manual.
+ */
+ vco_out = clkin / (plldf + 1);
+ vco_out *= 2 * (pllmf + 1);
+ bd->bi_vco = vco_out; /* Save for later */
+
+ bd->bi_cpmfreq = vco_out / 2; /* CPM Freq, in MHz */
+
+ /* Set Baud rate divisor. The power up default is divide by 16,
+ * but we set it again here in case it was changed.
+ */
+ ip->im_clkrst.car_sccr = 1; /* DIV 16 BRG */
+ bd->bi_brgfreq = vco_out / 16;
+}
+#endif
+
+#ifdef CONFIG_EST8260
+void
+embed_config(bd_t **bdp)
+{
+ u_char *cp;
+ int i;
+ bd_t *bd;
+
+ bd = *bdp;
+#if 0
+ /* This is actually provided by my boot rom. I have it
+ * here for those people that may load the kernel with
+ * a JTAG/COP tool and not the rom monitor.
+ */
+ bd->bi_baudrate = 115200;
+ bd->bi_intfreq = 200000000;
+ bd->bi_busfreq = 66666666;
+ bd->bi_cpmfreq = 66666666;
+ bd->bi_brgfreq = 33333333;
+ bd->bi_memsize = 16 * 1024 * 1024;
+#else
+ /* The boot rom passes these to us in MHz. Linux now expects
+ * them to be in Hz.
+ */
+ bd->bi_intfreq *= 1000000;
+ bd->bi_busfreq *= 1000000;
+ bd->bi_cpmfreq *= 1000000;
+ bd->bi_brgfreq *= 1000000;
+#endif
+
+ cp = (u_char *)def_enet_addr;
+ for (i=0; i<6; i++) {
+ bd->bi_enetaddr[i] = *cp++;
+ }
+}
+#endif /* EST8260 */
+
+#ifdef CONFIG_SBS8260
+/* We have to fill in everything.
+*/
+static bd_t bdinfo;
+
+void
+embed_config(bd_t **bdp)
+{
+ u_char *cp;
+ int i;
+ bd_t *bd;
+
+ /* This should provided by the boot rom.
+ */
+ bd = &bdinfo;
+ *bdp = bd;
+ bd->bi_baudrate = 9600;
+ bd->bi_memsize = 64 * 1024 * 1024;
+
+ /* Set all of the clocks. We have to know the speed of the
+ * external clock. The development board had 66 MHz.
+ */
+ bd->bi_busfreq = 66666666;
+ clk_8260(bd);
+
+ /* I don't know how to compute this yet.
+ */
+ bd->bi_intfreq = 133000000;
+
+
+ cp = (u_char *)def_enet_addr;
+ for (i=0; i<6; i++) {
+ bd->bi_enetaddr[i] = *cp++;
+ }
+}
+#endif /* SBS8260 */
+
+#ifdef CONFIG_RPX6
+/* The pointer we are given is for the string of key values.
+ */
+static bd_t bdinfo;
+
+void
+embed_config(bd_t **bdp)
+{
+ u_char *cp, *keyvals;
+ int i;
+ bd_t *bd;
+
+ keyvals = (u_char *)*bdp;
+
+ bd = &bdinfo;
+ *bdp = bd;
+
+ /* This is almost identical to the RPX-Lite/Classic functions
+ * on the 8xx boards. It would be nice to have a key lookup
+ * function in a string, but the format of all of the fields
+ * is slightly different.
+ */
+ cp = keyvals;
+ for (;;) {
+ if (*cp == 'E') {
+ cp++;
+ if (*cp == 'A') {
+ cp += 2;
+ rpx_eth(bd, cp);
+ }
+ }
+ if (*cp == 'S') {
+ cp++;
+ if (*cp == 'B') {
+ cp += 2;
+ bd->bi_baudrate = rpx_baseten(cp);
+ }
+ }
+ if (*cp == 'D') {
+ cp++;
+ if (*cp == '1') {
+ cp += 2;
+ bd->bi_memsize = rpx_baseten(cp) * 1024 * 1024;
+ }
+ }
+ if (*cp == 'X') {
+ cp++;
+ if (*cp == 'T') {
+ cp += 2;
+ bd->bi_busfreq = rpx_baseten(cp);
+ }
+ }
+ if (*cp == 'N') {
+ cp++;
+ if (*cp == 'V') {
+ cp += 2;
+ bd->bi_nvsize = rpx_baseten(cp) * 1024 * 1024;
+ }
+ }
+
+ /* Scan to the end of the record.
+ */
+ while ((*cp != '\n') && (*cp != 0xff))
+ cp++;
+
+ /* If the next character is a 0 or ff, we are done.
+ */
+ cp++;
+ if ((*cp == 0) || (*cp == 0xff))
+ break;
+ }
+ bd->bi_memstart = 0;
+
+ /* The memory size includes both the 60x and local bus DRAM.
+ * I don't want to use the local bus DRAM for real memory,
+ * so subtract it out. It would be nice if they were separate
+ * keys.
+ */
+ bd->bi_memsize -= 32 * 1024 * 1024;
+
+ /* Set all of the clocks. We have to know the speed of the
+ * external clock.
+ */
+ clk_8260(bd);
+
+ /* I don't know how to compute this yet.
+ */
+ bd->bi_intfreq = 200000000;
+}
+#endif /* RPX6 for testing */
+
+#ifdef CONFIG_ADS8260
+/* We have to fill in everything.
+*/
+static bd_t bdinfo;
+
+void
+embed_config(bd_t **bdp)
+{
+ u_char *cp;
+ int i;
+ bd_t *bd;
+
+ /* This should provided by the boot rom.
+ */
+ bd = &bdinfo;
+ *bdp = bd;
+ bd->bi_baudrate = 9600;
+ bd->bi_memsize = 16 * 1024 * 1024;
+
+ /* Set all of the clocks. We have to know the speed of the
+ * external clock. The development board had 66 MHz.
+ */
+ bd->bi_busfreq = 66666666;
+ clk_8260(bd);
+
+ /* I don't know how to compute this yet.
+ */
+ bd->bi_intfreq = 200000000;
+
+
+ cp = (u_char *)def_enet_addr;
+ for (i=0; i<6; i++) {
+ bd->bi_enetaddr[i] = *cp++;
+ }
+}
+#endif /* ADS8260 */
+
--- /dev/null
+/*
+ * BK Id: SCCS/s.gzimage.c 1.6 05/18/01 15:17:06 cort
+ */
+/*
+ * gzimage.c
+ *
+ * Dummy file to allow a compressed zImage to be added
+ * into a linker section, accessed by the boot coode
+ */
+
+char dummy_for_gzimage;
--- /dev/null
+/*
+ * BK Id: SCCS/s.head.S 1.9 05/18/01 07:54:04 patch
+ */
+#include <linux/config.h>
+#include "../../kernel/ppc_defs.h"
+#include "../../kernel/ppc_asm.tmpl"
+#include <asm/processor.h>
+#include <asm/cache.h>
+
+ .text
+
+/*
+ * This code is loaded by the ROM loader at some arbitrary location.
+ * Move it to high memory so that it can load the kernel at 0x0000.
+ *
+ * This is a three step process that will also work when booting from
+ * a Flash PROM normally located in high memory.
+ *
+ * First, the entire image is loaded into some high memory address.
+ * This is usually at or above 0x02000000. This is done by a network
+ * boot function supported by the board or a debugger over BDM port.
+ *
+ * Second, the start up function here will relocate the decompress
+ * function to run at the link address of 0x01000000.
+ *
+ * Last, the decompression function will reloate the initrd, zImage, and
+ * the residual data to locations under 8 Meg. This is necessary because
+ * the embedded kernel start up uses 8 Meg translations to access physical
+ * space before the MMU is enabled. Finally, the zImage is uncompressed
+ * to location 0 and we jump to it.
+ *
+ * On the MBX,
+ * R1 - Stack pointer at a high memory address.
+ * R3 - Pointer to Board Information Block.
+ * R4 - Pointer to argument string.
+ * Interrupts masked, cache and MMU disabled.
+ *
+ * ...and the first and second functions listed above are
+ * done for us (it knows ELF images).
+ *
+ * For other embedded boards we build the Board Information Block.
+ */
+
+ .globl start
+start:
+ bl start_
+start_:
+#ifndef CONFIG_MBX
+ lis r11, local_bd_info@h
+ ori r11, r11, local_bd_info@l
+#else
+ mr r11, r3
+#endif
+
+ mfmsr r3 /* Turn off interrupts */
+ li r4,0
+ ori r4,r4,MSR_EE
+ andc r3,r3,r4
+ mtmsr r3
+
+ li r4,0 /* Zero DER to prevent FRZ */
+ mtspr SPRN_DER,r4
+
+/* check if we need to relocate ourselves to the link addr or were we
+ loaded there to begin with -- Cort */
+ lis r4,start@h
+ ori r4,r4,start@l
+ mflr r3
+ subi r3,r3,4 /* we get the nip, not the ip of the branch */
+ mr r8,r3
+#if 0
+ cmp 0,r3,r4
+ beq start_ldr /* Branch if loaded OK */
+#endif
+
+/*
+ * no matter where we're loaded, move ourselves to -Ttext address
+ * This computes the sizes we need to determine other things.
+ */
+ lis r5,end@h
+ ori r5,r5,end@l
+ addi r5,r5,3 /* Round up - just in case */
+ sub r5,r5,r4 /* Compute # longwords to move */
+ srwi r5,r5,2
+ mtctr r5
+ mr r7,r5
+ li r6,0
+ subi r3,r3,4 /* Set up for loop */
+ subi r4,r4,4
+00: lwzu r5,4(r3)
+ stwu r5,4(r4)
+ xor r6,r6,r5
+ bdnz 00b
+
+ lis r3,start_ldr@h
+ ori r3,r3,start_ldr@l
+ mtlr r3 /* Easiest way to do an absolute jump */
+ blr
+
+start_ldr:
+/* Most 8xx boards don't boot up with the I-cache enabled. Do that
+ * now because the decompress runs much faster that way.
+ */
+ lis r3, IDC_INVALL@h
+ mtspr IC_CST, r3
+ lis r3, IDC_ENABLE@h
+ mtspr IC_CST, r3
+
+/* Clear all of BSS */
+ lis r3,edata@h
+ ori r3,r3,edata@l
+ lis r4,end@h
+ ori r4,r4,end@l
+ subi r3,r3,4
+ subi r4,r4,4
+ li r0,0
+50: stwu r0,4(r3)
+ cmp 0,r3,r4
+ bne 50b
+
+ lis r1,.stack@h
+ ori r1,r1,.stack@l
+ addi r1,r1,4096*2
+ subi r1,r1,256
+ li r2,0x000F /* Mask pointer to 16-byte boundary */
+ andc r1,r1,r2
+
+ /* Perform configuration of the various boards. This is done
+ * by reading some configuration data from EEPROM and building
+ * the board information structure.
+ */
+ mr r3, r11
+ mr r21, r11
+ mr r22, r8
+ mr r23, r7
+ mr r24, r6
+
+ bl embed_config
+ mr r3, r21
+ bl serial_init /* Init MBX serial port */
+
+ mr r11, r21
+ mr r8, r22
+ mr r7, r23
+ mr r6, r24
+
+#ifdef CONFIG_MBX
+ /* On the MBX (or anything that will TFTP load an ELF image),
+ * we have to find the intermediate address. The ELF loader
+ * only moves the Linux boostrap/decompress, not the zImage.
+ */
+#define ILAP_ADDRESS 0xfa000020
+ lis r8, ILAP_ADDRESS@h
+ lwz r8, ILAP_ADDRESS@l(r8)
+ addis r8, r8, 1 /* Add 64K */
+#endif
+
+ mr r3,r8 /* Load point */
+ mr r4,r7 /* Program length */
+ mr r5,r6 /* Checksum */
+ mr r6,r11 /* Residual data */
+ bl decompress_kernel
+
+ /* changed to use r3 (as firmware does) for kernel
+ as ptr to residual -- Cort*/
+ lis r6,cmd_line@h
+ ori r6,r6,cmd_line@l
+ lwz r6, 0(r6)
+ subi r7,r6,1
+00: lbzu r2,1(r7)
+ cmpi 0,r2,0
+ bne 00b
+
+ /* r4,r5 have initrd_start, size */
+ lis r2,initrd_start@h
+ ori r2,r2,initrd_start@l
+ lwz r4,0(r2)
+ lis r2,initrd_end@h
+ ori r2,r2,initrd_end@l
+ lwz r5,0(r2)
+
+ /* The world starts from the beginning.
+ */
+ li r9,0x0
+ mtlr r9
+
+ /* Invalidate the instruction cache because we just copied a
+ * bunch of kernel instructions.
+ */
+ lis r9, IDC_INVALL@h
+ mtspr IC_CST, r9
+
+ blr
+hang:
+ b hang
+
+/*
+ * Delay for a number of microseconds
+ * -- Use the BUS timer (assumes 66MHz)
+ */
+ .globl udelay
+udelay:
+ mulli r4,r3,1000 /* nanoseconds */
+ addi r4,r4,59
+ li r5,60
+ divw r4,r4,r5 /* BUS ticks */
+1: mftbu r5
+ mftb r6
+ mftbu r7
+ cmp 0,r5,r7
+ bne 1b /* Get [synced] base time */
+ addc r9,r6,r4 /* Compute end time */
+ addze r8,r5
+2: mftbu r5
+ cmp 0,r5,r8
+ blt 2b
+ bgt 3f
+ mftb r6
+ cmp 0,r6,r9
+ blt 2b
+3: blr
+
+.globl _get_MSR
+_get_MSR:
+ mfmsr r3
+ blr
+
+.globl _put_MSR
+_put_MSR:
+ mtmsr r3
+ blr
+
+ .comm .stack,4096*2,4
+#ifndef CONFIG_MBX
+local_bd_info:
+ .long 0
+ .long 0x01000000
+ .long 64
+ .long 64
+ .long 0
+ .long 0
+ .long 0
+#endif
--- /dev/null
+/*
+ * BK Id: SCCS/s.head_8260.S 1.8 05/18/01 07:54:04 patch
+ */
+#include "../../kernel/ppc_defs.h"
+#include "../../kernel/ppc_asm.tmpl"
+#include <asm/processor.h>
+#include <asm/cache.h>
+
+ .text
+
+/*
+ * Boot loader philosophy:
+ *
+ * ROM loads us to some arbitrary location
+ * ROM loads these registers:
+ *
+ * R3 = Pointer to the board configuration data
+ * R5 = Pointer to Open Firmware data
+ *
+ * ROM jumps to start/start_
+ * Move the boot code to the link address (4 MB)
+ * Call decompress_kernel()
+ * Relocate the initrd, zimage and residual data to 4 MB
+ * Decompress the kernel to 0
+ * Jump to the kernel entry
+ * -- Cort
+ */
+ .globl start
+start:
+ bl start_
+start_:
+ mr r11,r3 /* Save pointer to residual/board data */
+ mr r25,r5 /* Save OFW pointer */
+ li r3,MSR_IP /* Establish default MSR value */
+ mtmsr r3
+
+/* check if we need to relocate ourselves to the link addr or were we
+ loaded there to begin with -- Cort */
+ lis r4,start@h
+ ori r4,r4,start@l
+ mflr r3
+ subi r3,r3,4 /* we get the nip, not the ip of the branch */
+ mr r8,r3
+ cmp 0,r3,r4
+ bne 1010f
+/* compute size of whole image in words. this should be moved to
+ * start_ldr() -- Cort
+ */
+ lis r4,start@h
+ ori r4,r4,start@l
+ lis r5,end@h
+ ori r5,r5,end@l
+ addi r5,r5,3 /* round up */
+ sub r5,r5,r4
+ srwi r5,r5,2
+ mr r7,r5
+ b start_ldr
+1010:
+/*
+ * no matter where we're loaded, move ourselves to -Ttext address
+ */
+relocate:
+ mflr r3 /* Compute code bias */
+ subi r3,r3,4
+ mr r8,r3
+ lis r4,start@h
+ ori r4,r4,start@l
+ lis r5,end@h
+ ori r5,r5,end@l
+ addi r5,r5,3 /* Round up - just in case */
+ sub r5,r5,r4 /* Compute # longwords to move */
+ srwi r5,r5,2
+ mtctr r5
+ mr r7,r5
+ li r6,0
+ subi r3,r3,4 /* Set up for loop */
+ subi r4,r4,4
+00: lwzu r5,4(r3)
+ stwu r5,4(r4)
+ xor r6,r6,r5
+ bdnz 00b
+ lis r3,start_ldr@h
+ ori r3,r3,start_ldr@l
+ mtlr r3 /* Easiest way to do an absolute jump */
+ blr
+start_ldr:
+/* Clear all of BSS */
+ lis r3,edata@h
+ ori r3,r3,edata@l
+ lis r4,end@h
+ ori r4,r4,end@l
+ subi r3,r3,4
+ subi r4,r4,4
+ li r0,0
+50: stwu r0,4(r3)
+ cmp 0,r3,r4
+ bne 50b
+90: mr r9,r1 /* Save old stack pointer (in case it matters) */
+ lis r1,.stack@h
+ ori r1,r1,.stack@l
+ addi r1,r1,4096*2
+ subi r1,r1,256
+ li r2,0x000F /* Mask pointer to 16-byte boundary */
+ andc r1,r1,r2
+
+ /* Speed us up a little.
+ */
+ bl flush_instruction_cache
+
+/* Run loader */
+ mr r3,r8 /* Load point */
+ mr r4,r7 /* Program length */
+ mr r5,r6 /* Checksum */
+ mr r6,r11 /* Residual data */
+ mr r7,r25 /* OFW interfaces */
+ bl decompress_kernel
+
+ /* changed to use r3 (as firmware does) for kernel
+ as ptr to residual -- Cort*/
+ lis r6,cmd_line@h
+ ori r6,r6,cmd_line@l
+ lwz r6, 0(r6)
+ subi r7,r6,1
+00: lbzu r2,1(r7)
+ cmpi 0,r2,0
+ bne 00b
+
+ /* r4,r5 have initrd_start, size */
+ lis r2,initrd_start@h
+ ori r2,r2,initrd_start@l
+ lwz r4,0(r2)
+ lis r2,initrd_end@h
+ ori r2,r2,initrd_end@l
+ lwz r5,0(r2)
+
+ /* tell kernel we're prep */
+ /*
+ * get start address of kernel code which is stored as a coff
+ * entry. see boot/head.S -- Cort
+ */
+ li r9,0x4
+ mtlr r9
+ lis r10,0xdeadc0de@h
+ ori r10,r10,0xdeadc0de@l
+ li r9,0
+ stw r10,0(r9)
+/*
+ * The Radstone firmware maps PCI memory at 0xc0000000 using BAT2
+ * so disable BATs before setting this to avoid a clash
+ */
+ li r8,0
+ mtspr DBAT0U,r8
+ mtspr DBAT1U,r8
+ mtspr DBAT2U,r8
+ mtspr DBAT3U,r8
+ mtspr IBAT0U,r8
+ mtspr IBAT1U,r8
+ mtspr IBAT2U,r8
+ mtspr IBAT3U,r8
+
+ blr
+hang:
+ b hang
+
+/*
+ * Delay for a number of microseconds
+ * -- Use the BUS timer (assumes 66MHz)
+ */
+ .globl udelay
+udelay:
+ mfspr r4,PVR
+ srwi r4,r4,16
+ cmpi 0,r4,1 /* 601 ? */
+ bne .udelay_not_601
+00: li r0,86 /* Instructions / microsecond? */
+ mtctr r0
+10: addi r0,r0,0 /* NOP */
+ bdnz 10b
+ subic. r3,r3,1
+ bne 00b
+ blr
+
+.udelay_not_601:
+ mulli r4,r3,1000 /* nanoseconds */
+ addi r4,r4,59
+ li r5,60
+ divw r4,r4,r5 /* BUS ticks */
+1: mftbu r5
+ mftb r6
+ mftbu r7
+ cmp 0,r5,r7
+ bne 1b /* Get [synced] base time */
+ addc r9,r6,r4 /* Compute end time */
+ addze r8,r5
+2: mftbu r5
+ cmp 0,r5,r8
+ blt 2b
+ bgt 3f
+ mftb r6
+ cmp 0,r6,r9
+ blt 2b
+3: blr
+
+.globl _get_HID0
+_get_HID0:
+ mfspr r3,HID0
+ blr
+
+.globl _put_HID0
+_put_HID0:
+ mtspr HID0,r3
+ blr
+
+.globl _get_MSR
+_get_MSR:
+ mfmsr r3
+ blr
+
+.globl _put_MSR
+_put_MSR:
+ mtmsr r3
+ blr
+
+/*
+ * Flush instruction cache
+ * *** I'm really paranoid here!
+ */
+_GLOBAL(flush_instruction_cache)
+ mflr r5
+ bl flush_data_cache
+ mfspr r3,HID0 /* Caches are controlled by this register */
+ li r4,0
+ ori r4,r4,(HID0_ICE|HID0_ICFI)
+ or r3,r3,r4 /* Need to enable+invalidate to clear */
+ mtspr HID0,r3
+ andc r3,r3,r4
+ ori r3,r3,HID0_ICE /* Enable cache */
+ mtspr HID0,r3
+ mtlr r5
+ blr
+
+#define NUM_CACHE_LINES 128*8
+#define CACHE_LINE_SIZE 32
+#define cache_flush_buffer 0x1000
+
+/*
+ * Flush data cache
+ * *** I'm really paranoid here!
+ */
+_GLOBAL(flush_data_cache)
+ lis r3,cache_flush_buffer@h
+ ori r3,r3,cache_flush_buffer@l
+ li r4,NUM_CACHE_LINES
+ mtctr r4
+00: lwz r4,0(r3)
+ addi r3,r3,CACHE_LINE_SIZE /* Next line, please */
+ bdnz 00b
+10: blr
+ .comm .stack,4096*2,4
--- /dev/null
+/*
+ * BK Id: SCCS/s.iic.c 1.8 05/18/01 07:54:04 patch
+ */
+
+/* Minimal support functions to read configuration from IIC EEPROMS
+ * on MPC8xx boards. Originally written for RPGC RPX-Lite.
+ * Dan Malek (dmalek@jlc.net).
+ */
+#include <linux/types.h>
+#include <asm/uaccess.h>
+#include <asm/mpc8xx.h>
+#include "../../8xx_io/commproc.h"
+
+
+/* IIC functions.
+ * These are just the basic master read/write operations so we can
+ * examine serial EEPROM.
+ */
+void iic_read(uint devaddr, u_char *buf, uint offset, uint count);
+
+static int iic_init_done;
+
+static void
+iic_init()
+{
+ volatile iic_t *iip;
+ volatile i2c8xx_t *i2c;
+ volatile cpm8xx_t *cp;
+ volatile immap_t *immap;
+ uint dpaddr;
+
+ immap = (immap_t *)IMAP_ADDR;
+ cp = (cpm8xx_t *)&(immap->im_cpm);
+
+ /* Reset the CPM. This is necessary on the 860 processors
+ * that may have started the SCC1 ethernet without relocating
+ * the IIC.
+ * This also stops the Ethernet in case we were loaded by a
+ * BOOTP rom monitor.
+ */
+ cp->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG);
+
+ /* Wait for it.
+ */
+ while (cp->cp_cpcr & (CPM_CR_RST | CPM_CR_FLG));
+
+ /* Remove any microcode patches. We will install our own
+ * later.
+ */
+ cp->cp_cpmcr1 = 0;
+ cp->cp_cpmcr2 = 0;
+ cp->cp_cpmcr3 = 0;
+ cp->cp_cpmcr4 = 0;
+ cp->cp_rccr = 0;
+
+ iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
+ i2c = (i2c8xx_t *)&(immap->im_i2c);
+
+ /* Initialize Port B IIC pins.
+ */
+ cp->cp_pbpar |= 0x00000030;
+ cp->cp_pbdir |= 0x00000030;
+ cp->cp_pbodr |= 0x00000030;
+
+ /* Initialize the parameter ram.
+ */
+
+ /* Allocate space for a two transmit and one receive buffer
+ * descriptor in the DP ram.
+ * For now, this address seems OK, but it may have to
+ * change with newer versions of the firmware.
+ */
+ dpaddr = 0x0840;
+
+ /* Set up the IIC parameters in the parameter ram.
+ */
+ iip->iic_tbase = dpaddr;
+ iip->iic_rbase = dpaddr + (2 * sizeof(cbd_t));
+
+ iip->iic_tfcr = SMC_EB;
+ iip->iic_rfcr = SMC_EB;
+
+ /* This should really be done by the reader/writer.
+ */
+ iip->iic_mrblr = 128;
+
+ /* Initialize Tx/Rx parameters.
+ */
+ cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+ while (cp->cp_cpcr & CPM_CR_FLG);
+
+ /* Select an arbitrary address. Just make sure it is unique.
+ */
+ i2c->i2c_i2add = 0x34;
+
+ /* Make clock run maximum slow.
+ */
+ i2c->i2c_i2brg = 7;
+
+ /* Disable interrupts.
+ */
+ i2c->i2c_i2cmr = 0;
+ i2c->i2c_i2cer = 0xff;
+
+ /* Enable SDMA.
+ */
+ immap->im_siu_conf.sc_sdcr = 1;
+
+ iic_init_done = 1;
+}
+
+/* Read from IIC.
+ * Caller provides device address, memory buffer, and byte count.
+ */
+static u_char iitemp[32];
+
+void
+iic_read(uint devaddr, u_char *buf, uint offset, uint count)
+{
+ volatile iic_t *iip;
+ volatile i2c8xx_t *i2c;
+ volatile cbd_t *tbdf, *rbdf;
+ volatile cpm8xx_t *cp;
+ volatile immap_t *immap;
+ u_char *tb;
+ uint temp;
+
+ /* If the interface has not been initialized, do that now.
+ */
+ if (!iic_init_done)
+ iic_init();
+
+ immap = (immap_t *)IMAP_ADDR;
+ cp = (cpm8xx_t *)&(immap->im_cpm);
+
+ iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
+ i2c = (i2c8xx_t *)&(immap->im_i2c);
+
+ tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase];
+ rbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_rbase];
+
+ /* Send a "dummy write" operation. This is a write request with
+ * only the offset sent, followed by another start condition.
+ * This will ensure we start reading from the first location
+ * of the EEPROM.
+ */
+ tb = iitemp;
+ tb = (u_char *)(((uint)tb + 15) & ~15);
+ tbdf->cbd_bufaddr = (int)tb;
+ *tb = devaddr & 0xfe; /* Device address */
+ *(tb+1) = offset; /* Offset */
+ tbdf->cbd_datlen = 2; /* Length */
+ tbdf->cbd_sc =
+ BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START;
+
+ i2c->i2c_i2mod = 1; /* Enable */
+ i2c->i2c_i2cer = 0xff;
+ i2c->i2c_i2com = 0x81; /* Start master */
+
+ /* Wait for IIC transfer.
+ */
+#if 0
+ while ((i2c->i2c_i2cer & 3) == 0);
+
+ if (tbdf->cbd_sc & BD_SC_READY)
+ printf("IIC ra complete but tbuf ready\n");
+#else
+ temp = 10000000;
+ while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0))
+ temp--;
+#if 0
+ /* We can't do this...there is no serial port yet!
+ */
+ if (temp == 0) {
+ printf("Timeout reading EEPROM\n");
+ return;
+ }
+#endif
+#endif
+
+ /* Chip errata, clear enable.
+ */
+ i2c->i2c_i2mod = 0;
+
+ /* To read, we need an empty buffer of the proper length.
+ * All that is used is the first byte for address, the remainder
+ * is just used for timing (and doesn't really have to exist).
+ */
+ tbdf->cbd_bufaddr = (int)tb;
+ *tb = devaddr | 1; /* Device address */
+ rbdf->cbd_bufaddr = (uint)buf; /* Desination buffer */
+ tbdf->cbd_datlen = rbdf->cbd_datlen = count + 1; /* Length */
+ tbdf->cbd_sc = BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START;
+ rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
+
+ /* Chip bug, set enable here.
+ */
+ i2c->i2c_i2mod = 1; /* Enable */
+ i2c->i2c_i2cer = 0xff;
+ i2c->i2c_i2com = 0x81; /* Start master */
+
+ /* Wait for IIC transfer.
+ */
+#if 0
+ while ((i2c->i2c_i2cer & 1) == 0);
+
+ if (rbdf->cbd_sc & BD_SC_EMPTY)
+ printf("IIC read complete but rbuf empty\n");
+#else
+ temp = 10000000;
+ while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0))
+ temp--;
+#endif
+
+ /* Chip errata, clear enable.
+ */
+ i2c->i2c_i2mod = 0;
+}
--- /dev/null
+/*
+ * BK Id: SCCS/s.m8260_tty.c 1.7 05/18/01 07:54:04 patch
+ */
+
+
+/* Minimal serial functions needed to send messages out the serial
+ * port on SMC1.
+ */
+#include <linux/types.h>
+#include <asm/mpc8260.h>
+#include <asm/cpm_8260.h>
+
+uint no_print;
+extern char *params[];
+extern int nparams;
+static u_char cons_hold[128], *sgptr;
+static int cons_hold_cnt;
+
+/* If defined, enables serial console. The value (1 through 4)
+ * should designate which SCC is used, but this isn't complete. Only
+ * SCC1 is known to work at this time.
+ */
+#ifdef CONFIG_SCC_CONSOLE
+#define SCC_CONSOLE 1
+#endif
+
+void
+serial_init(bd_t *bd)
+{
+ volatile smc_t *sp;
+ volatile smc_uart_t *up;
+ volatile scc_t *sccp;
+ volatile scc_uart_t *sup;
+ volatile cbd_t *tbdf, *rbdf;
+ volatile immap_t *ip;
+ volatile iop8260_t *io;
+ volatile cpm8260_t *cp;
+ uint dpaddr, memaddr;
+
+ ip = (immap_t *)IMAP_ADDR;
+ cp = &ip->im_cpm;
+ io = &ip->im_ioport;
+
+ /* Perform a reset.
+ */
+ cp->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG);
+
+ /* Wait for it.
+ */
+ while (cp->cp_cpcr & CPM_CR_FLG);
+
+#ifdef CONFIG_ADS8260
+ /* Enable the RS-232 transceivers.
+ */
+ *(volatile uint *)(BCSR_ADDR + 4) &=
+ ~(BCSR1_RS232_EN1 | BCSR1_RS232_EN2);
+#endif
+
+#ifdef SCC_CONSOLE
+ sccp = (scc_t *)&(ip->im_scc[SCC_CONSOLE-1]);
+ sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)];
+ sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX);
+ sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+ /* Use Port D for SCC1 instead of other functions.
+ */
+ io->iop_ppard |= 0x00000003;
+ io->iop_psord &= ~0x00000001; /* Rx */
+ io->iop_psord |= 0x00000002; /* Tx */
+ io->iop_pdird &= ~0x00000001; /* Rx */
+ io->iop_pdird |= 0x00000002; /* Tx */
+
+#else
+ sp = (smc_t*)&(ip->im_smc[0]);
+ *(ushort *)(&ip->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1;
+ up = (smc_uart_t *)&ip->im_dprambase[PROFF_SMC1];
+
+ /* Disable transmitter/receiver.
+ */
+ sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
+
+ /* Use Port D for SMC1 instead of other functions.
+ */
+ io->iop_ppard |= 0x00c00000;
+ io->iop_pdird |= 0x00400000;
+ io->iop_pdird &= ~0x00800000;
+ io->iop_psord &= ~0x00c00000;
+#endif
+
+ /* Allocate space for two buffer descriptors in the DP ram.
+ * For now, this address seems OK, but it may have to
+ * change with newer versions of the firmware.
+ */
+ dpaddr = 0x0800;
+
+ /* Grab a few bytes from the top of memory.
+ */
+ memaddr = (bd->bi_memsize - 256) & ~15;
+
+ /* Set the physical address of the host memory buffers in
+ * the buffer descriptors.
+ */
+ rbdf = (cbd_t *)&ip->im_dprambase[dpaddr];
+ rbdf->cbd_bufaddr = memaddr;
+ rbdf->cbd_sc = 0;
+ tbdf = rbdf + 1;
+ tbdf->cbd_bufaddr = memaddr+128;
+ tbdf->cbd_sc = 0;
+
+ /* Set up the uart parameters in the parameter ram.
+ */
+#ifdef SCC_CONSOLE
+ sup->scc_genscc.scc_rbase = dpaddr;
+ sup->scc_genscc.scc_tbase = dpaddr + sizeof(cbd_t);
+
+ /* Set up the uart parameters in the
+ * parameter ram.
+ */
+ sup->scc_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB;
+ sup->scc_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB;
+
+ sup->scc_genscc.scc_mrblr = 128;
+ sup->scc_maxidl = 8;
+ sup->scc_brkcr = 1;
+ sup->scc_parec = 0;
+ sup->scc_frmec = 0;
+ sup->scc_nosec = 0;
+ sup->scc_brkec = 0;
+ sup->scc_uaddr1 = 0;
+ sup->scc_uaddr2 = 0;
+ sup->scc_toseq = 0;
+ sup->scc_char1 = 0x8000;
+ sup->scc_char2 = 0x8000;
+ sup->scc_char3 = 0x8000;
+ sup->scc_char4 = 0x8000;
+ sup->scc_char5 = 0x8000;
+ sup->scc_char6 = 0x8000;
+ sup->scc_char7 = 0x8000;
+ sup->scc_char8 = 0x8000;
+ sup->scc_rccm = 0xc0ff;
+
+ /* Send the CPM an initialize command.
+ */
+ cp->cp_cpcr = mk_cr_cmd(CPM_CR_SCC1_PAGE, CPM_CR_SCC1_SBLOCK, 0,
+ CPM_CR_INIT_TRX) | CPM_CR_FLG;
+ while (cp->cp_cpcr & CPM_CR_FLG);
+
+ /* Set UART mode, 8 bit, no parity, one stop.
+ * Enable receive and transmit.
+ */
+ sccp->scc_gsmrh = 0;
+ sccp->scc_gsmrl =
+ (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
+
+ /* Disable all interrupts and clear all pending
+ * events.
+ */
+ sccp->scc_sccm = 0;
+ sccp->scc_scce = 0xffff;
+ sccp->scc_dsr = 0x7e7e;
+ sccp->scc_pmsr = 0x3000;
+
+ /* Wire BRG1 to SCC1. The console driver will take care of
+ * others.
+ */
+ ip->im_cpmux.cmx_scr = 0;
+#else
+ up->smc_rbase = dpaddr;
+ up->smc_tbase = dpaddr+sizeof(cbd_t);
+ up->smc_rfcr = CPMFCR_EB;
+ up->smc_tfcr = CPMFCR_EB;
+ up->smc_brklen = 0;
+ up->smc_brkec = 0;
+ up->smc_brkcr = 0;
+ up->smc_mrblr = 128;
+ up->smc_maxidl = 8;
+
+ /* Set UART mode, 8 bit, no parity, one stop.
+ * Enable receive and transmit.
+ */
+ sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART;
+
+ /* Mask all interrupts and remove anything pending.
+ */
+ sp->smc_smcm = 0;
+ sp->smc_smce = 0xff;
+
+ /* Set up the baud rate generator.
+ */
+ ip->im_cpmux.cmx_smr = 0;
+#endif
+
+ /* The baud rate divisor needs to be coordinated with clk_8260().
+ */
+ ip->im_brgc1 =
+ (((bd->bi_brgfreq/16) / bd->bi_baudrate) << 1) |
+ CPM_BRG_EN;
+
+ /* Make the first buffer the only buffer.
+ */
+ tbdf->cbd_sc |= BD_SC_WRAP;
+ rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
+
+ /* Initialize Tx/Rx parameters.
+ */
+#ifdef SCC_CONSOLE
+ sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#else
+ cp->cp_cpcr = mk_cr_cmd(CPM_CR_SMC1_PAGE, CPM_CR_SMC1_SBLOCK, 0, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+ while (cp->cp_cpcr & CPM_CR_FLG);
+
+ /* Enable transmitter/receiver.
+ */
+ sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
+#endif
+}
+
+void
+serial_putc(void *ignored, const char c)
+{
+ volatile cbd_t *tbdf;
+ volatile char *buf;
+ volatile smc_uart_t *up;
+ volatile scc_uart_t *sup;
+ volatile immap_t *ip;
+ extern bd_t *board_info;
+
+ ip = (immap_t *)IMAP_ADDR;
+#ifdef SCC_CONSOLE
+ sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)];
+ tbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_tbase];
+#else
+ up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]);
+ tbdf = (cbd_t *)&ip->im_dprambase[up->smc_tbase];
+#endif
+
+ /* Wait for last character to go.
+ */
+ buf = (char *)tbdf->cbd_bufaddr;
+ while (tbdf->cbd_sc & BD_SC_READY);
+
+ *buf = c;
+ tbdf->cbd_datlen = 1;
+ tbdf->cbd_sc |= BD_SC_READY;
+}
+
+char
+serial_getc(void *ignored)
+{
+ char c;
+
+ if (cons_hold_cnt <= 0) {
+ cons_hold_cnt = serial_readbuf(cons_hold);
+ sgptr = cons_hold;
+ }
+ c = *sgptr++;
+ cons_hold_cnt--;
+
+ return(c);
+}
+
+int
+serial_readbuf(u_char *cbuf)
+{
+ volatile cbd_t *rbdf;
+ volatile char *buf;
+ volatile smc_uart_t *up;
+ volatile scc_uart_t *sup;
+ volatile immap_t *ip;
+ int i, nc;
+
+ ip = (immap_t *)IMAP_ADDR;
+
+#ifdef SCC_CONSOLE
+ sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)];
+ rbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_rbase];
+#else
+ up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]);
+ rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase];
+#endif
+
+ /* Wait for character to show up.
+ */
+ buf = (char *)rbdf->cbd_bufaddr;
+ while (rbdf->cbd_sc & BD_SC_EMPTY);
+ nc = rbdf->cbd_datlen;
+ for (i=0; i<nc; i++)
+ *cbuf++ = *buf++;
+ rbdf->cbd_sc |= BD_SC_EMPTY;
+
+ return(nc);
+}
+
+int
+serial_tstc(void *ignored)
+{
+ volatile cbd_t *rbdf;
+ volatile smc_uart_t *up;
+ volatile scc_uart_t *sup;
+ volatile immap_t *ip;
+
+ ip = (immap_t *)IMAP_ADDR;
+#ifdef SCC_CONSOLE
+ sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)];
+ rbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_rbase];
+#else
+ up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]);
+ rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase];
+#endif
+
+ return(!(rbdf->cbd_sc & BD_SC_EMPTY));
+}
--- /dev/null
+/*
+ * BK Id: SCCS/s.m8xx_tty.c 1.8 05/18/01 07:54:04 patch
+ */
+
+
+/* Minimal serial functions needed to send messages out the serial
+ * port on the MBX console.
+ *
+ * The MBX uxes SMC1 for the serial port. We reset the port and use
+ * only the first BD that EPPC-Bug set up as a character FIFO.
+ *
+ * Later versions (at least 1.4, maybe earlier) of the MBX EPPC-Bug
+ * use COM1 instead of SMC1 as the console port. This kinda sucks
+ * for the rest of the kernel, so here we force the use of SMC1 again.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <asm/uaccess.h>
+#include <asm/mpc8xx.h>
+#include "../../8xx_io/commproc.h"
+
+#ifdef CONFIG_MBX
+#define MBX_CSR1 ((volatile u_char *)0xfa100000)
+#define CSR1_COMEN (u_char)0x02
+#endif
+
+#ifdef TQM_SMC2_CONSOLE
+#define PROFF_CONS PROFF_SMC2
+#define CPM_CR_CH_CONS CPM_CR_CH_SMC2
+#define SMC_INDEX 1
+static volatile iop8xx_t *iopp = (iop8xx_t *)&(((immap_t *)IMAP_ADDR)->im_ioport);
+#else
+#define PROFF_CONS PROFF_SMC1
+#define CPM_CR_CH_CONS CPM_CR_CH_SMC1
+#define SMC_INDEX 0
+#endif
+
+static cpm8xx_t *cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
+
+void
+serial_init(bd_t *bd)
+{
+ volatile smc_t *sp;
+ volatile smc_uart_t *up;
+ volatile cbd_t *tbdf, *rbdf;
+ volatile cpm8xx_t *cp;
+ uint dpaddr, memaddr, ui;
+
+ cp = cpmp;
+ sp = (smc_t*)&(cp->cp_smc[SMC_INDEX]);
+ up = (smc_uart_t *)&cp->cp_dparam[PROFF_CONS];
+
+ /* Disable transmitter/receiver.
+ */
+ sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
+
+#ifdef CONFIG_FADS
+ /* Enable SMC1/2 transceivers.
+ */
+ *((volatile uint *)BCSR1) &= ~(BCSR1_RS232EN_1|BCSR1_RS232EN_2);
+#endif
+
+#ifndef CONFIG_MBX
+ {
+ /* Initialize SMCx and use it for the console port.
+ */
+
+ /* Enable SDMA.
+ */
+ ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1;
+
+#ifdef TQM_SMC2_CONSOLE
+ /* Use Port A for SMC2 instead of other functions.
+ */
+ iopp->iop_papar |= 0x00c0;
+ iopp->iop_padir &= ~0x00c0;
+ iopp->iop_paodr &= ~0x00c0;
+#else
+ /* Use Port B for SMCs instead of other functions.
+ */
+ cp->cp_pbpar |= 0x00000cc0;
+ cp->cp_pbdir &= ~0x00000cc0;
+ cp->cp_pbodr &= ~0x00000cc0;
+#endif
+
+ /* Allocate space for two buffer descriptors in the DP ram.
+ * For now, this address seems OK, but it may have to
+ * change with newer versions of the firmware.
+ */
+ dpaddr = 0x0800;
+
+ /* Grab a few bytes from the top of memory for SMC FIFOs.
+ */
+ memaddr = (bd->bi_memsize - 32) & ~15;
+
+ /* Set the physical address of the host memory buffers in
+ * the buffer descriptors.
+ */
+ rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr];
+ rbdf->cbd_bufaddr = memaddr;
+ rbdf->cbd_sc = 0;
+ tbdf = rbdf + 1;
+ tbdf->cbd_bufaddr = memaddr+4;
+ tbdf->cbd_sc = 0;
+
+ /* Set up the uart parameters in the parameter ram.
+ */
+ up->smc_rbase = dpaddr;
+ up->smc_tbase = dpaddr+sizeof(cbd_t);
+ up->smc_rfcr = SMC_EB;
+ up->smc_tfcr = SMC_EB;
+
+ /* Set UART mode, 8 bit, no parity, one stop.
+ * Enable receive and transmit.
+ */
+ sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART;
+
+ /* Mask all interrupts and remove anything pending.
+ */
+ sp->smc_smcm = 0;
+ sp->smc_smce = 0xff;
+
+ /* Set up the baud rate generator.
+ * See 8xx_io/commproc.c for details.
+ * This wires BRG1 to SMC1 and BRG2 to SMC2;
+ */
+ cp->cp_simode = 0x10000000;
+ ui = bd->bi_intfreq / 16 / bd->bi_baudrate;
+#ifdef TQM_SMC2_CONSOLE
+ cp->cp_brgc2 =
+#else
+ cp->cp_brgc1 =
+#endif
+ ((ui - 1) < 4096)
+ ? (((ui - 1) << 1) | CPM_BRG_EN)
+ : ((((ui / 16) - 1) << 1) | CPM_BRG_EN | CPM_BRG_DIV16);
+
+#else /* CONFIG_MBX */
+ if (*MBX_CSR1 & CSR1_COMEN) {
+ /* COM1 is enabled. Initialize SMC1 and use it for
+ * the console port.
+ */
+
+ /* Enable SDMA.
+ */
+ ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1;
+
+ /* Use Port B for SMCs instead of other functions.
+ */
+ cp->cp_pbpar |= 0x00000cc0;
+ cp->cp_pbdir &= ~0x00000cc0;
+ cp->cp_pbodr &= ~0x00000cc0;
+
+ /* Allocate space for two buffer descriptors in the DP ram.
+ * For now, this address seems OK, but it may have to
+ * change with newer versions of the firmware.
+ */
+ dpaddr = 0x0800;
+
+ /* Grab a few bytes from the top of memory. EPPC-Bug isn't
+ * running any more, so we can do this.
+ */
+ memaddr = (bd->bi_memsize - 32) & ~15;
+
+ /* Set the physical address of the host memory buffers in
+ * the buffer descriptors.
+ */
+ rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr];
+ rbdf->cbd_bufaddr = memaddr;
+ rbdf->cbd_sc = 0;
+ tbdf = rbdf + 1;
+ tbdf->cbd_bufaddr = memaddr+4;
+ tbdf->cbd_sc = 0;
+
+ /* Set up the uart parameters in the parameter ram.
+ */
+ up->smc_rbase = dpaddr;
+ up->smc_tbase = dpaddr+sizeof(cbd_t);
+ up->smc_rfcr = SMC_EB;
+ up->smc_tfcr = SMC_EB;
+
+ /* Set UART mode, 8 bit, no parity, one stop.
+ * Enable receive and transmit.
+ */
+ sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART;
+
+ /* Mask all interrupts and remove anything pending.
+ */
+ sp->smc_smcm = 0;
+ sp->smc_smce = 0xff;
+
+ /* Set up the baud rate generator.
+ * See 8xx_io/commproc.c for details.
+ */
+ cp->cp_simode = 0x10000000;
+ cp->cp_brgc1 =
+ (((bd->bi_intfreq/16) / 9600) << 1) | CPM_BRG_EN;
+
+ /* Enable SMC1 for console output.
+ */
+ *MBX_CSR1 &= ~CSR1_COMEN;
+ }
+ else {
+#endif /* ndef CONFIG_MBX */
+ /* SMCx is used as console port.
+ */
+ tbdf = (cbd_t *)&cp->cp_dpmem[up->smc_tbase];
+ rbdf = (cbd_t *)&cp->cp_dpmem[up->smc_rbase];
+
+ /* Issue a stop transmit, and wait for it.
+ */
+ cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS,
+ CPM_CR_STOP_TX) | CPM_CR_FLG;
+ while (cp->cp_cpcr & CPM_CR_FLG);
+ }
+
+ /* Make the first buffer the only buffer.
+ */
+ tbdf->cbd_sc |= BD_SC_WRAP;
+ rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
+
+ /* Single character receive.
+ */
+ up->smc_mrblr = 1;
+ up->smc_maxidl = 0;
+
+ /* Initialize Tx/Rx parameters.
+ */
+ cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+ while (cp->cp_cpcr & CPM_CR_FLG);
+
+ /* Enable transmitter/receiver.
+ */
+ sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
+}
+
+void
+serial_putc(void *ignored, const char c)
+{
+ volatile cbd_t *tbdf;
+ volatile char *buf;
+ volatile smc_uart_t *up;
+
+ up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];
+ tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];
+
+ /* Wait for last character to go.
+ */
+ buf = (char *)tbdf->cbd_bufaddr;
+ while (tbdf->cbd_sc & BD_SC_READY);
+
+ *buf = c;
+ tbdf->cbd_datlen = 1;
+ tbdf->cbd_sc |= BD_SC_READY;
+}
+
+char
+serial_getc(void *ignored)
+{
+ volatile cbd_t *rbdf;
+ volatile char *buf;
+ volatile smc_uart_t *up;
+ char c;
+
+ up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];
+ rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
+
+ /* Wait for character to show up.
+ */
+ buf = (char *)rbdf->cbd_bufaddr;
+ while (rbdf->cbd_sc & BD_SC_EMPTY);
+ c = *buf;
+ rbdf->cbd_sc |= BD_SC_EMPTY;
+
+ return(c);
+}
+
+int
+serial_tstc(void *ignored)
+{
+ volatile cbd_t *rbdf;
+ volatile smc_uart_t *up;
+
+ up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];
+ rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
+
+ return(!(rbdf->cbd_sc & BD_SC_EMPTY));
+}
--- /dev/null
+/*
+ * BK Id: SCCS/s.misc.c 1.9 05/18/01 07:54:04 patch
+ */
+/*
+ * Adapted for PowerPC by Gary Thomas
+ *
+ * Rewritten by Cort Dougan (cort@cs.nmt.edu)
+ * One day to be replaced by a single bootloader for chrp/prep/pmac. -- Cort
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include "zlib.h"
+#include <asm/residual.h>
+#include <linux/elf.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/mmu.h>
+#ifdef CONFIG_8xx
+#include <asm/mpc8xx.h>
+#endif
+#ifdef CONFIG_8260
+#include <asm/mpc8260.h>
+#endif
+
+/*
+ * The following references are needed to cause the linker to pull in the
+ * gzimage.o and rdimage.o files. These object files are special,
+ * since they get placed into the .gzimage and .rdimage ELF sections
+ * of the zvmlinux and zvmlinux.initrd files.
+ */
+extern char dummy_for_gzimage;
+extern char dummy_for_rdimage;
+
+/*
+ * Please send me load/board info and such data for hardware not
+ * listed here so I can keep track since things are getting tricky
+ * with the different load addrs with different firmware. This will
+ * help to avoid breaking the load/boot process.
+ * -- Cort
+ */
+char *avail_ram;
+char *end_avail;
+
+/* See comment below.....
+*/
+unsigned int initrd_offset, initrd_size;
+
+/* Because of the limited amount of memory on embedded, it presents
+ * loading problems. The biggest is that we load this boot program
+ * into a relatively low memory address, and the Linux kernel Bss often
+ * extends into this space when it get loaded. When the kernel starts
+ * and zeros the BSS space, it also writes over the information we
+ * save here and pass to the kernel (command line and board info).
+ * On these boards, we grab some known memory holes to hold this information.
+ */
+char cmd_buf[256];
+char *cmd_line = cmd_buf;
+
+/* This is the default cmdline that will be given to the user at boot time..
+ * If none was specified at compile time, we'll give it one that should work.
+ * -- Tom */
+#ifdef CONFIG_CMDLINE_BOOL
+char compiled_string[] = CONFIG_CMDLINE;
+#endif
+char ramroot_string[] = "root=/dev/ram";
+char netroot_string[] = "root=/dev/nfs rw";
+
+bd_t hold_resid_buf;
+bd_t *hold_residual = &hold_resid_buf;
+unsigned long initrd_start = 0, initrd_end = 0;
+char *zimage_start;
+int zimage_size;
+
+extern void puts(const char *);
+extern void putc(const char c);
+extern void udelay(long x);
+extern void puthex(unsigned long val);
+extern void * memcpy(void * __dest, __const void * __src, __kernel_size_t __n);
+extern void gunzip(void *, int, unsigned char *, int *);
+extern int tstc(void);
+extern int getc(void);
+
+unsigned long
+decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, bd_t *bp)
+{
+ int timer;
+ extern unsigned long start;
+ char *cp, ch;
+
+#ifdef CONFIG_8260
+ /* I don't know why I didn't do it this way on the 8xx.......
+ */
+ embed_config(&bp);
+ serial_init(bp);
+#endif
+
+ /* These values must be variables. If not, the compiler optimizer
+ * will remove some code, causing the size of the code to vary
+ * when these values are zero. This is bad because we first
+ * compile with these zero to determine the size and offsets
+ * in an image, than compile again with these set to the proper
+ * discovered value.....Ya know, we used to read these from the
+ * header a long time ago.....
+ */
+ initrd_offset = INITRD_OFFSET;
+ initrd_size = INITRD_SIZE;
+
+ /* Grab some space for the command line and board info. Since
+ * we no longer use the ELF header, but it was loaded, grab
+ * that space.
+ */
+#ifdef CONFIG_MBX
+ cmd_line = (char *)(load_addr - 0x10000);
+
+ /* To be like everyone else, we need one too, although this
+ * board information is passed from the boot rom.
+ */
+ bp->bi_baudrate = 9600;
+#else
+ cmd_line = (char *)(0x200000);
+#endif
+ hold_residual = (bd_t *)(cmd_line + sizeof(cmd_buf));
+ /* copy board data */
+ if (bp)
+ memcpy(hold_residual,bp,sizeof(bd_t));
+
+ /* Set end of memory available to us. It is always the highest
+ * memory address provided by the board information.
+ */
+ end_avail = (char *)(bp->bi_memsize);
+
+ puts("loaded at: "); puthex(load_addr);
+ puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n");
+ if ( (unsigned long)load_addr != (unsigned long)&start )
+ {
+ puts("relocated to: "); puthex((unsigned long)&start);
+ puts(" ");
+ puthex((unsigned long)((unsigned long)&start + (4*num_words)));
+ puts("\n");
+ }
+
+ if ( bp )
+ {
+ puts("board data at: "); puthex((unsigned long)bp);
+ puts(" ");
+ puthex((unsigned long)((unsigned long)bp + sizeof(bd_t)));
+ puts("\n");
+ puts("relocated to: ");
+ puthex((unsigned long)hold_residual);
+ puts(" ");
+ puthex((unsigned long)((unsigned long)hold_residual + sizeof(bd_t)));
+ puts("\n");
+ }
+
+ /* we have to subtract 0x10000 here to correct for objdump including the
+ size of the elf header which we strip -- Cort */
+ zimage_start = (char *)(load_addr - 0x10000 + ZIMAGE_OFFSET);
+ zimage_size = ZIMAGE_SIZE;
+
+ if ( initrd_offset )
+ initrd_start = load_addr - 0x10000 + initrd_offset;
+ else
+ initrd_start = 0;
+ initrd_end = initrd_size + initrd_start;
+
+ /*
+ * setup avail_ram - this is the first part of ram usable
+ * by the uncompress code. -- Cort
+ */
+ avail_ram = (char *)PAGE_ALIGN((unsigned long)zimage_start+zimage_size);
+ if ( ((load_addr+(num_words*4)) > (unsigned long) avail_ram)
+ && (load_addr <= 0x01000000) )
+ avail_ram = (char *)(load_addr+(num_words*4));
+ if ( (((unsigned long)&start+(num_words*4)) > (unsigned long) avail_ram)
+ && (load_addr <= 0x01000000) )
+ avail_ram = (char *)((unsigned long)&start+(num_words*4));
+
+ /* relocate zimage */
+ puts("zimage at: "); puthex((unsigned long)zimage_start);
+ puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); puts("\n");
+ /*
+ * There is no reason (yet) to relocate zImage for embedded boards.
+ * To support boot from flash rom on 8xx embedded boards, I
+ * assume if zimage start is over 16M we are booting from flash.
+ * In this case, avilable ram will start just above the space we
+ * have allocated for the command buffer and board information.
+ */
+ if ((unsigned long)zimage_start > 0x01000000)
+ avail_ram = (char *)PAGE_ALIGN((unsigned long)hold_residual + sizeof(bd_t));
+
+ /* relocate initrd */
+ if ( initrd_start )
+ {
+ puts("initrd at: "); puthex(initrd_start);
+ puts(" "); puthex(initrd_end); puts("\n");
+
+ /* We only have to relocate initrd if we find it is in Flash
+ * rom. This is because the kernel thinks it can toss the
+ * pages into the free memory pool after it is done. Use
+ * the same 16M test.
+ */
+ if ((unsigned long)initrd_start > 0x01000000) {
+ memcpy ((void *)PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-INITRD_SIZE),
+ (void *)initrd_start,
+ initrd_size );
+ initrd_start = PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-INITRD_SIZE);
+ initrd_end = initrd_start + initrd_size;
+ end_avail = (char *)initrd_start;
+ puts("relocated to: "); puthex(initrd_start);
+ puts(" "); puthex(initrd_end); puts("\n");
+ }
+ else {
+ avail_ram = (char *)PAGE_ALIGN((unsigned long)initrd_end);
+ }
+ }
+
+
+ puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" ");
+ puthex((unsigned long)end_avail); puts("\n");
+ puts("\nLinux/PPC load: ");
+ timer = 0;
+ cp = cmd_line;
+ /* This is where we try and pick the right command line for booting.
+ * If we were given one at compile time, use it. It Is Right.
+ * If we weren't, see if we have a ramdisk. If so, thats root.
+ * When in doubt, give them the netroot (root=/dev/nfs rw) -- Tom */
+#ifdef CONFIG_CMDLINE_BOOL
+ memcpy (cmd_line, compiled_string, sizeof(compiled_string));
+#else
+ if (initrd_start)
+ memcpy (cmd_line, ramroot_string, sizeof(ramroot_string));
+ else
+ memcpy (cmd_line, netroot_string, sizeof(netroot_string));
+#endif
+ while ( *cp ) putc(*cp++);
+ while (timer++ < 5*1000) {
+ if (tstc()) {
+ while ((ch = getc()) != '\n' && ch != '\r') {
+ if (ch == '\b' || ch == '\177') {
+ if (cp != cmd_line) {
+ cp--;
+ puts("\b \b");
+ }
+ } else if (ch == '\030' /* ^x */
+ || ch == '\025') { /* ^u */
+ while (cp != cmd_line) {
+ cp--;
+ puts("\b \b");
+ }
+ } else {
+ *cp++ = ch;
+ putc(ch);
+ }
+ }
+ break; /* Exit 'timer' loop */
+ }
+ udelay(1000); /* 1 msec */
+ }
+ *cp = 0;
+ puts("\nUncompressing Linux...");
+
+ gunzip(0, 0x400000, zimage_start, &zimage_size);
+ puts("done.\n");
+ puts("Now booting the kernel\n");
+ return (unsigned long)hold_residual;
+}
+
+/*
+ * PCI/ISA I/O support
+ */
+
+volatile unsigned char *ISA_io = (unsigned char *)0x80000000;
+volatile unsigned char *ISA_mem = (unsigned char *)0xC0000000;
+
+void
+outb(int port, char val)
+{
+ /* Ensure I/O operations complete */
+ __asm__ volatile("eieio");
+ ISA_io[port] = val;
+}
+
+unsigned char
+inb(int port)
+{
+ /* Ensure I/O operations complete */
+ __asm__ volatile("eieio");
+ return (ISA_io[port]);
+}
+
+unsigned long
+local_to_PCI(unsigned long addr)
+{
+ return ((addr & 0x7FFFFFFF) | 0x80000000);
+}
--- /dev/null
+/*
+ * BK Id: SCCS/s.pci.c 1.6 05/18/01 15:17:06 cort
+ */
+/* Stand alone funtions for QSpan Tundra support.
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <asm/mpc8xx.h>
+
+/* To map PCI devices, you first write 0xffffffff into the device
+ * base address registers. When the register is read back, the
+ * number of most significant '1' bits describes the amount of address
+ * space needed for mapping. If the most significant bit is not set,
+ * either the device does not use that address register, or it has
+ * a fixed address that we can't change. After the address is assigned,
+ * the command register has to be written to enable the card.
+ */
+typedef struct {
+ u_char pci_bus;
+ u_char pci_devfn;
+ ushort pci_command;
+ uint pci_addrs[6];
+} pci_map_t;
+
+/* We should probably dynamically allocate these structures.
+*/
+#define MAX_PCI_DEVS 32
+int pci_dev_cnt;
+pci_map_t pci_map[MAX_PCI_DEVS];
+
+void pci_conf_write(int bus, int device, int func, int reg, uint writeval);
+void pci_conf_read(int bus, int device, int func, int reg, void *readval);
+void probe_addresses(int bus, int devfn);
+void map_pci_addrs(void);
+
+/* This is a really stripped version of PCI bus scan. All we are
+ * looking for are devices that exist.
+ */
+pci_scanner(int addr_probe)
+{
+ unsigned int devfn, l, max, class, bus_number;
+ unsigned char cmd, irq, tmp, hdr_type, is_multi;
+ int reg;
+
+ is_multi = 0;
+ bus_number = 0;
+ for (devfn = 0; devfn < 0xff; ++devfn) {
+ /* The device numbers are comprised of upper 5 bits of
+ * device number and lower 3 bits of multi-function number.
+ */
+ if ((devfn & 7) && !is_multi) {
+ /* Don't scan multifunction addresses if this is
+ * not a multifunction device.
+ */
+ continue;
+ }
+
+ /* Read the header to determine card type.
+ */
+ qs_pci_read_config_byte(bus_number, devfn, PCI_HEADER_TYPE,
+ &hdr_type);
+
+ /* If this is a base device number, check the header to
+ * determine if it is mulifunction.
+ */
+ if ((devfn & 7) == 0)
+ is_multi = hdr_type & 0x80;
+
+ /* Check to see if the board is really in the slot.
+ */
+ qs_pci_read_config_dword(bus_number, devfn, PCI_VENDOR_ID, &l);
+ /* some broken boards return 0 if a slot is empty: */
+ if (l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff ||
+ l == 0xffff0000) {
+ /* Nothing there.
+ */
+ is_multi = 0;
+ continue;
+ }
+
+ /* If we are not performing an address probe,
+ * just simply print out some information.
+ */
+ if (!addr_probe) {
+ qs_pci_read_config_dword(bus_number, devfn,
+ PCI_CLASS_REVISION, &class);
+
+ class >>= 8; /* upper 3 bytes */
+
+#if 0
+ printf("Found (%3d:%d): vendor 0x%04x, device 0x%04x, class 0x%06x\n",
+ (devfn >> 3), (devfn & 7),
+ (l & 0xffff), (l >> 16) & 0xffff, class);
+#else
+ puts("Found ("); puthex(devfn >> 3);
+ puts(":"); puthex(devfn & 7);
+ puts("): vendor "); puthex(l & 0xffff);
+ puts(", device "); puthex((l >> 16) & 0xffff);
+ puts(", class "); puthex(class); puts("\n");
+#endif
+ }
+ else {
+ /* If this is a "normal" device, build address list.
+ */
+ if ((hdr_type & 0x7f) == PCI_HEADER_TYPE_NORMAL)
+ probe_addresses(bus_number, devfn);
+ }
+ }
+
+ /* Now map the boards.
+ */
+ if (addr_probe)
+ map_pci_addrs();
+}
+
+/* Probe addresses for the specified device. This is a destructive
+ * operation because it writes the registers.
+ */
+void
+probe_addresses(bus, devfn)
+{
+ int i;
+ uint pciaddr;
+ ushort pcicmd;
+ pci_map_t *pm;
+
+ if (pci_dev_cnt >= MAX_PCI_DEVS) {
+ puts("Too many PCI devices\n");
+ return;
+ }
+
+ pm = &pci_map[pci_dev_cnt++];
+
+ pm->pci_bus = bus;
+ pm->pci_devfn = devfn;
+
+ for (i=0; i<6; i++) {
+ qs_pci_write_config_dword(bus, devfn, PCI_BASE_ADDRESS_0 + (i * 4), -1);
+ qs_pci_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0 + (i * 4),
+ &pciaddr);
+ pm->pci_addrs[i] = pciaddr;
+ qs_pci_read_config_word(bus, devfn, PCI_COMMAND, &pcicmd);
+ pm->pci_command = pcicmd;
+ }
+}
+
+/* Map the cards into the PCI space. The PCI has separate memory
+ * and I/O spaces. In addition, some memory devices require mapping
+ * below 1M. The least significant 4 bits of the address register
+ * provide information. If this is an I/O device, only the LS bit
+ * is used to indicate that, so I/O devices can be mapped to a two byte
+ * boundard. Memory addresses can be mapped to a 32 byte boundary.
+ * The QSpan implementations usually have a 1Gbyte space for each
+ * memory and I/O spaces.
+ *
+ * This isn't a terribly fancy algorithm. I just map the spaces from
+ * the top starting with the largest address space. When finished,
+ * the registers are written and the card enabled.
+ *
+ * While the Tundra can map a large address space on most boards, we
+ * need to be careful because it may overlap other devices (like IMMR).
+ */
+#define MEMORY_SPACE_SIZE 0x20000000
+#define IO_SPACE_SIZE 0x20000000
+
+void
+map_pci_addrs()
+{
+ uint pci_mem_top, pci_mem_low;
+ uint pci_io_top;
+ uint addr_mask, reg_addr, space;
+ int i, j;
+ pci_map_t *pm;
+
+ pci_mem_top = MEMORY_SPACE_SIZE;
+ pci_io_top = IO_SPACE_SIZE;
+ pci_mem_low = (1 * 1024 * 1024); /* Below one meg addresses */
+
+ /* We can't map anything more than the maximum space, but test
+ * for it anyway to catch devices out of range.
+ */
+ addr_mask = 0x80000000;
+
+ do {
+ space = (~addr_mask) + 1; /* Size of the space */
+ for (i=0; i<pci_dev_cnt; i++) {
+ pm = &pci_map[i];
+ for (j=0; j<6; j++) {
+ /* If the MS bit is not set, this has either
+ * already been mapped, or is not used.
+ */
+ reg_addr = pm->pci_addrs[j];
+ if ((reg_addr & 0x80000000) == 0)
+ continue;
+ if (reg_addr & PCI_BASE_ADDRESS_SPACE_IO) {
+ if ((reg_addr & PCI_BASE_ADDRESS_IO_MASK) != addr_mask)
+ continue;
+ if (pci_io_top < space) {
+ puts("Out of PCI I/O space\n");
+ }
+ else {
+ pci_io_top -= space;
+ pm->pci_addrs[j] = pci_io_top;
+ pm->pci_command |= PCI_COMMAND_IO;
+ }
+ }
+ else {
+ if ((reg_addr & PCI_BASE_ADDRESS_MEM_MASK) != addr_mask)
+ continue;
+
+ /* Memory space. Test if below 1M.
+ */
+ if (reg_addr & PCI_BASE_ADDRESS_MEM_TYPE_1M) {
+ if (pci_mem_low < space) {
+ puts("Out of PCI 1M space\n");
+ }
+ else {
+ pci_mem_low -= space;
+ pm->pci_addrs[j] = pci_mem_low;
+ }
+ }
+ else {
+ if (pci_mem_top < space) {
+ puts("Out of PCI Mem space\n");
+ }
+ else {
+ pci_mem_top -= space;
+ pm->pci_addrs[j] = pci_mem_top;
+ }
+ }
+ pm->pci_command |= PCI_COMMAND_MEMORY;
+ }
+ }
+ }
+ addr_mask >>= 1;
+ addr_mask |= 0x80000000;
+ } while (addr_mask != 0xfffffffe);
+
+ /* Now, run the list one more time and map everything.
+ */
+ for (i=0; i<pci_dev_cnt; i++) {
+ pm = &pci_map[i];
+ for (j=0; j<6; j++) {
+ qs_pci_write_config_dword(pm->pci_bus, pm->pci_devfn,
+ PCI_BASE_ADDRESS_0 + (j * 4), pm->pci_addrs[j]);
+ }
+
+ /* Enable memory or address mapping.
+ */
+ qs_pci_write_config_word(pm->pci_bus, pm->pci_devfn, PCI_COMMAND,
+ pm->pci_command);
+ }
+}
+
--- /dev/null
+/*
+ * BK Id: SCCS/s.qspan_pci.c 1.6 05/18/01 15:17:06 cort
+ */
+/*
+ * LinuxPPC arch/ppc/kernel/qspan_pci.c Dan Malek (dmalek@jlc.net)
+ *
+ * QSpan Motorola bus to PCI bridge. The config address register
+ * is located 0x500 from the base of the bridge control/status registers.
+ * The data register is located at 0x504.
+ * This is a two step operation. First, the address register is written,
+ * then the data register is read/written as required.
+ * I don't know what to do about interrupts (yet).
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <asm/mpc8xx.h>
+
+/*
+ * When reading the configuration space, if something does not respond
+ * the bus times out and we get a machine check interrupt. So, the
+ * good ol' exception tables come to mind to trap it and return some
+ * value.
+ *
+ * On an error we just return a -1, since that is what the caller wants
+ * returned if nothing is present. I copied this from __get_user_asm,
+ * with the only difference of returning -1 instead of EFAULT.
+ * There is an associated hack in the machine check trap code.
+ *
+ * The QSPAN is also a big endian device, that is it makes the PCI
+ * look big endian to us. This presents a problem for the Linux PCI
+ * functions, which assume little endian. For example, we see the
+ * first 32-bit word like this:
+ * ------------------------
+ * | Device ID | Vendor ID |
+ * ------------------------
+ * If we read/write as a double word, that's OK. But in our world,
+ * when read as a word, device ID is at location 0, not location 2 as
+ * the little endian PCI would believe. We have to switch bits in
+ * the PCI addresses given to us to get the data to/from the correct
+ * byte lanes.
+ *
+ * The QSPAN only supports 4 bits of "slot" in the dev_fn instead of 5.
+ * It always forces the MS bit to zero. Therefore, dev_fn values
+ * greater than 128 are returned as "no device found" errors.
+ *
+ * The QSPAN can only perform long word (32-bit) configuration cycles.
+ * The "offset" must have the two LS bits set to zero. Read operations
+ * require we read the entire word and then sort out what should be
+ * returned. Write operations other than long word require that we
+ * read the long word, update the proper word or byte, then write the
+ * entire long word back.
+ *
+ * PCI Bridge hack. We assume (correctly) that bus 0 is the primary
+ * PCI bus from the QSPAN. If we are called with a bus number other
+ * than zero, we create a Type 1 configuration access that a downstream
+ * PCI bridge will interpret.
+ */
+
+#define __get_pci_config(x, addr, op) \
+ __asm__ __volatile__( \
+ "1: "op" %0,0(%1)\n" \
+ " eieio\n" \
+ "2:\n" \
+ ".section .fixup,\"ax\"\n" \
+ "3: li %0,-1\n" \
+ " b 2b\n" \
+ ".section __ex_table,\"a\"\n" \
+ " .align 2\n" \
+ " .long 1b,3b\n" \
+ ".text" \
+ : "=r"(x) : "r"(addr))
+
+#define QS_CONFIG_ADDR ((volatile uint *)(PCI_CSR_ADDR + 0x500))
+#define QS_CONFIG_DATA ((volatile uint *)(PCI_CSR_ADDR + 0x504))
+
+#define mk_config_addr(bus, dev, offset) \
+ (((bus)<<16) | ((dev)<<8) | (offset & 0xfc))
+
+#define mk_config_type1(bus, dev, offset) \
+ mk_config_addr(bus, dev, offset) | 1;
+
+/* Initialize the QSpan device registers after power up.
+*/
+qspan_init()
+{
+ uint *qptr;
+
+
+
+ qptr = (uint *)PCI_CSR_ADDR;
+
+ /* PCI Configuration/status. Upper bits written to clear
+ * pending interrupt or status. Lower bits enable QSPAN as
+ * PCI master, enable memory and I/O cycles, and enable PCI
+ * parity error checking.
+ * IMPORTANT: The last two bits of this word enable PCI
+ * master cycles into the QBus. The QSpan is broken and can't
+ * meet the timing specs of the PQ bus for this to work. Therefore,
+ * if you don't have external bus arbitration, you can't use
+ * this function.
+ */
+#ifdef EXTERNAL_PQ_ARB
+ qptr[1] = 0xf9000147;
+#else
+ qptr[1] = 0xf9000144;
+#endif
+
+ /* PCI Misc configuration. Set PCI latency timer resolution
+ * of 8 cycles, set cache size to 4 x 32.
+ */
+ qptr[3] = 0;
+
+ /* Set up PCI Target address mapping. Enable, Posted writes,
+ * 2Gbyte space (processor memory controller determines actual size).
+ */
+ qptr[64] = 0x8f000080;
+
+ /* Map processor 0x80000000 to PCI 0x00000000.
+ * Processor address bit 1 determines I/O type access (0x80000000)
+ * or memory type access (0xc0000000).
+ */
+ qptr[65] = 0x80000000;
+
+ /* Enable error logging and clear any pending error status.
+ */
+ qptr[80] = 0x90000000;
+
+ qptr[512] = 0x000c0003;
+
+ /* Set up Qbus slave image.
+ */
+ qptr[960] = 0x01000000;
+ qptr[961] = 0x000000d1;
+ qptr[964] = 0x00000000;
+ qptr[965] = 0x000000d1;
+
+}
+
+/* Functions to support PCI bios-like features to read/write configuration
+ * space. If the function fails for any reason, a -1 (0xffffffff) value
+ * must be returned.
+ */
+#define DEVICE_NOT_FOUND (-1)
+#define SUCCESSFUL 0
+
+int qs_pci_read_config_byte(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned char *val)
+{
+ uint temp;
+ u_char *cp;
+
+ if ((bus > 7) || (dev_fn > 127)) {
+ *val = 0xff;
+ return DEVICE_NOT_FOUND;
+ }
+
+ if (bus == 0)
+ *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
+ else
+ *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
+ __get_pci_config(temp, QS_CONFIG_DATA, "lwz");
+
+ offset ^= 0x03;
+ cp = ((u_char *)&temp) + (offset & 0x03);
+ *val = *cp;
+ return SUCCESSFUL;
+}
+
+int qs_pci_read_config_word(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned short *val)
+{
+ uint temp;
+ ushort *sp;
+
+ if ((bus > 7) || (dev_fn > 127)) {
+ *val = 0xffff;
+ return DEVICE_NOT_FOUND;
+ }
+
+ if (bus == 0)
+ *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
+ else
+ *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
+ __get_pci_config(temp, QS_CONFIG_DATA, "lwz");
+ offset ^= 0x02;
+
+ sp = ((ushort *)&temp) + ((offset >> 1) & 1);
+ *val = *sp;
+ return SUCCESSFUL;
+}
+
+int qs_pci_read_config_dword(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned int *val)
+{
+ if ((bus > 7) || (dev_fn > 127)) {
+ *val = 0xffffffff;
+ return DEVICE_NOT_FOUND;
+ }
+ if (bus == 0)
+ *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
+ else
+ *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
+ __get_pci_config(*val, QS_CONFIG_DATA, "lwz");
+ return SUCCESSFUL;
+}
+
+int qs_pci_write_config_byte(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned char val)
+{
+ uint temp;
+ u_char *cp;
+
+ if ((bus > 7) || (dev_fn > 127))
+ return DEVICE_NOT_FOUND;
+
+ qs_pci_read_config_dword(bus, dev_fn, offset, &temp);
+
+ offset ^= 0x03;
+ cp = ((u_char *)&temp) + (offset & 0x03);
+ *cp = val;
+
+ if (bus == 0)
+ *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
+ else
+ *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
+ *QS_CONFIG_DATA = temp;
+
+ return SUCCESSFUL;
+}
+
+int qs_pci_write_config_word(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned short val)
+{
+ uint temp;
+ ushort *sp;
+
+ if ((bus > 7) || (dev_fn > 127))
+ return DEVICE_NOT_FOUND;
+
+ qs_pci_read_config_dword(bus, dev_fn, offset, &temp);
+
+ offset ^= 0x02;
+ sp = ((ushort *)&temp) + ((offset >> 1) & 1);
+ *sp = val;
+
+ if (bus == 0)
+ *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
+ else
+ *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
+ *QS_CONFIG_DATA = temp;
+
+ return SUCCESSFUL;
+}
+
+int qs_pci_write_config_dword(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned int val)
+{
+ if ((bus > 7) || (dev_fn > 127))
+ return DEVICE_NOT_FOUND;
+
+ if (bus == 0)
+ *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
+ else
+ *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
+ *(unsigned int *)QS_CONFIG_DATA = val;
+
+ return SUCCESSFUL;
+}
+
--- /dev/null
+/*
+ * BK Id: SCCS/s.rdimage.c 1.6 05/18/01 15:17:06 cort
+ */
+/*
+ * rdimage.c
+ *
+ * Dummy file to allow a compressed initrd to be added
+ * into a linker section, accessed by the boot coode
+ */
+
+char dummy_for_rdimage;
+++ /dev/null
-/*
- * misc.c
- *
- * $Id: misc.c,v 1.68 1999/10/20 22:08:08 cort Exp $
- *
- * Adapted for PowerPC by Gary Thomas
- *
- * Rewritten by Cort Dougan (cort@cs.nmt.edu)
- * One day to be replaced by a single bootloader for chrp/prep/pmac. -- Cort
- */
-
-#include <linux/types.h>
-#include "../coffboot/zlib.h"
-#include "asm/residual.h"
-#include <linux/elf.h>
-#include <linux/config.h>
-#include <asm/page.h>
-#include <asm/processor.h>
-#include <asm/bootinfo.h>
-#include <asm/mmu.h>
-#if defined(CONFIG_SERIAL_CONSOLE)
-#include "ns16550.h"
-struct NS16550 *com_port;
-#endif /* CONFIG_SERIAL_CONSOLE */
-
-/*
- * Please send me load/board info and such data for hardware not
- * listed here so I can keep track since things are getting tricky
- * with the different load addrs with different firmware. This will
- * help to avoid breaking the load/boot process.
- * -- Cort
- */
-char *avail_ram;
-char *end_avail;
-extern char _end[];
-
-#ifdef CONFIG_CMDLINE
-#define CMDLINE CONFIG_CMDLINE
-#else
-#define CMDLINE "";
-#endif
-char cmd_preset[] = CMDLINE;
-char cmd_buf[256];
-char *cmd_line = cmd_buf;
-
-int keyb_present = 1; /* keyboard controller is present by default */
-RESIDUAL hold_resid_buf;
-RESIDUAL *hold_residual = &hold_resid_buf;
-unsigned long initrd_start = 0, initrd_end = 0;
-char *zimage_start;
-int zimage_size;
-
-char *vidmem = (char *)0xC00B8000;
-int lines, cols;
-int orig_x, orig_y;
-
-void puts(const char *);
-void putc(const char c);
-void puthex(unsigned long val);
-void _bcopy(char *src, char *dst, int len);
-void * memcpy(void * __dest, __const void * __src,
- int __n);
-void gunzip(void *, int, unsigned char *, int *);
-static int _cvt(unsigned long val, char *buf, long radix, char *digits);
-unsigned char inb(int);
-
-void pause()
-{
- puts("pause\n");
-}
-
-void exit()
-{
- puts("exit\n");
- while(1);
-}
-
-static void clear_screen()
-{
- int i, j;
- for (i = 0; i < lines; i++) {
- for (j = 0; j < cols; j++) {
- vidmem[((i*cols)+j)*2] = ' ';
- vidmem[((i*cols)+j)*2+1] = 0x07;
- }
- }
-}
-
-static void scroll()
-{
- int i;
-
- memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 );
- for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 )
- vidmem[i] = ' ';
-}
-
-tstc(void)
-{
-#if defined(CONFIG_SERIAL_CONSOLE)
- if (keyb_present)
- return (CRT_tstc() || NS16550_tstc(com_port));
- else
- NS16550_tstc(com_port);
-#else
- return (CRT_tstc() );
-#endif /* CONFIG_SERIAL_CONSOLE */
-}
-
-getc(void)
-{
- while (1) {
-#if defined(CONFIG_SERIAL_CONSOLE)
- if (NS16550_tstc(com_port)) return (NS16550_getc(com_port));
-#endif /* CONFIG_SERIAL_CONSOLE */
- if (keyb_present)
- if (CRT_tstc()) return (CRT_getc());
- }
-}
-
-void
-putc(const char c)
-{
- int x,y;
-
-#if defined(CONFIG_SERIAL_CONSOLE)
- NS16550_putc(com_port, c);
- if ( c == '\n' ) NS16550_putc(com_port, '\r');
-#endif /* CONFIG_SERIAL_CONSOLE */
-
- x = orig_x;
- y = orig_y;
-
- if ( c == '\n' ) {
- x = 0;
- if ( ++y >= lines ) {
- scroll();
- y--;
- }
- } else if (c == '\r') {
- x = 0;
- } else if (c == '\b') {
- if (x > 0) {
- x--;
- }
- } else {
- vidmem [ ( x + cols * y ) * 2 ] = c;
- if ( ++x >= cols ) {
- x = 0;
- if ( ++y >= lines ) {
- scroll();
- y--;
- }
- }
- }
-
- cursor(x, y);
-
- orig_x = x;
- orig_y = y;
-}
-
-void puts(const char *s)
-{
- int x,y;
- char c;
-
- x = orig_x;
- y = orig_y;
-
- while ( ( c = *s++ ) != '\0' ) {
-#if defined(CONFIG_SERIAL_CONSOLE)
- NS16550_putc(com_port, c);
- if ( c == '\n' ) NS16550_putc(com_port, '\r');
-#endif /* CONFIG_SERIAL_CONSOLE */
-
- if ( c == '\n' ) {
- x = 0;
- if ( ++y >= lines ) {
- scroll();
- y--;
- }
- } else if (c == '\b') {
- if (x > 0) {
- x--;
- }
- } else {
- vidmem [ ( x + cols * y ) * 2 ] = c;
- if ( ++x >= cols ) {
- x = 0;
- if ( ++y >= lines ) {
- scroll();
- y--;
- }
- }
- }
- }
-
- cursor(x, y);
-
- orig_x = x;
- orig_y = y;
-}
-
-void * memcpy(void * __dest, __const void * __src,
- int __n)
-{
- int i;
- char *d = (char *)__dest, *s = (char *)__src;
-
- for (i=0;i<__n;i++) d[i] = s[i];
-}
-
-int memcmp(__const void * __dest, __const void * __src,
- int __n)
-{
- int i;
- char *d = (char *)__dest, *s = (char *)__src;
-
- for (i=0;i<__n;i++, d++, s++)
- {
- if (*d != *s)
- {
- return (*s - *d);
- }
- }
- return (0);
-}
-
-void error(char *x)
-{
- puts("\n\n");
- puts(x);
- puts("\n\n -- System halted");
-
- while(1); /* Halt */
-}
-
-void *zalloc(void *x, unsigned items, unsigned size)
-{
- void *p = avail_ram;
-
- size *= items;
- size = (size + 7) & -8;
- avail_ram += size;
- if (avail_ram > end_avail) {
- puts("oops... out of memory\n");
- pause();
- }
- return p;
-}
-
-void zfree(void *x, void *addr, unsigned nb)
-{
-}
-
-#define HEAD_CRC 2
-#define EXTRA_FIELD 4
-#define ORIG_NAME 8
-#define COMMENT 0x10
-#define RESERVED 0xe0
-
-#define DEFLATED 8
-
-
-void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
-{
- z_stream s;
- int r, i, flags;
-
- /* skip header */
- i = 10;
- flags = src[3];
- if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
- puts("bad gzipped data\n");
- exit();
- }
- if ((flags & EXTRA_FIELD) != 0)
- i = 12 + src[10] + (src[11] << 8);
- if ((flags & ORIG_NAME) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & COMMENT) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & HEAD_CRC) != 0)
- i += 2;
- if (i >= *lenp) {
- puts("gunzip: ran out of data in header\n");
- exit();
- }
-
- s.zalloc = zalloc;
- s.zfree = zfree;
- r = inflateInit2(&s, -MAX_WBITS);
- if (r != Z_OK) {
- puts("inflateInit2 returned %d\n");
- exit();
- }
- s.next_in = src + i;
- s.avail_in = *lenp - i;
- s.next_out = dst;
- s.avail_out = dstlen;
- r = inflate(&s, Z_FINISH);
- if (r != Z_OK && r != Z_STREAM_END) {
- puts("inflate returned %d\n");
- exit();
- }
- *lenp = s.next_out - (unsigned char *) dst;
- inflateEnd(&s);
-}
-
-unsigned long
-decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
- RESIDUAL *residual, void *OFW_interface)
-{
- int timer;
- extern unsigned long start;
- char *cp, ch;
- unsigned long i;
- BATU *u;
- BATL *l;
- unsigned long TotalMemory;
- unsigned long orig_MSR;
- int dev_handle;
- int mem_info[2];
- int res, size;
- unsigned char board_type;
- unsigned char base_mod;
-
- lines = 25;
- cols = 80;
- orig_x = 0;
- orig_y = 24;
-
- /*
- * IBM's have the MMU on, so we have to disable it or
- * things get really unhappy in the kernel when
- * trying to setup the BATs with the MMU on
- * -- Cort
- */
- flush_instruction_cache();
- _put_HID0(_get_HID0() & ~0x0000C000);
- _put_MSR((orig_MSR = _get_MSR()) & ~0x0030);
-
-#if defined(CONFIG_SERIAL_CONSOLE)
- com_port = (struct NS16550 *)NS16550_init(0);
-#endif /* CONFIG_SERIAL_CONSOLE */
- vga_init(0xC0000000);
-
- if (residual)
- {
- /* Is this Motorola PPCBug? */
- if ((1 & residual->VitalProductData.FirmwareSupports) &&
- (1 == residual->VitalProductData.FirmwareSupplier)) {
- board_type = inb(0x800) & 0xF0;
-
- /* If this is genesis 2 board then check for no
- * keyboard controller and more than one processor.
- */
- if (board_type == 0xe0) {
- base_mod = inb(0x803);
- /* if a MVME2300/2400 or a Sitka then no keyboard */
- if((base_mod == 0xFA) || (base_mod == 0xF9) ||
- (base_mod == 0xE1)) {
- keyb_present = 0; /* no keyboard */
- }
- }
- }
- memcpy(hold_residual,residual,sizeof(RESIDUAL));
- } else {
- /* Assume 32M in the absence of more info... */
- TotalMemory = 0x02000000;
- /*
- * This is a 'best guess' check. We want to make sure
- * we don't try this on a PReP box without OF
- * -- Cort
- */
- while (OFW_interface && ((unsigned long)OFW_interface < 0x10000000) )
- {
- /* The MMU needs to be on when we call OFW */
- _put_MSR(orig_MSR);
- of_init(OFW_interface);
-
- /* get handle to memory description */
- res = of_finddevice("/memory@0",
- &dev_handle);
- // puthex(res); puts("\n");
- if (res) break;
-
- /* get the info */
- // puts("get info = ");
- res = of_getprop(dev_handle,
- "reg",
- mem_info,
- sizeof(mem_info),
- &size);
- // puthex(res); puts(", info = "); puthex(mem_info[0]);
- // puts(" "); puthex(mem_info[1]); puts("\n");
- if (res) break;
-
- TotalMemory = mem_info[1];
- break;
- }
- hold_residual->TotalMemory = TotalMemory;
- residual = hold_residual;
- /* Turn MMU back off */
- _put_MSR(orig_MSR & ~0x0030);
- }
-
- /* assume the chunk below 8M is free */
- end_avail = (char *)0x00800000;
-
- /* tell the user where we were loaded at and where we
- * were relocated to for debugging this process
- */
- puts("loaded at: "); puthex(load_addr);
- puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n");
- if ( (unsigned long)load_addr != (unsigned long)&start )
- {
- puts("relocated to: "); puthex((unsigned long)&start);
- puts(" ");
- puthex((unsigned long)((unsigned long)&start + (4*num_words)));
- puts("\n");
- }
-
- if ( residual )
- {
- puts("board data at: "); puthex((unsigned long)residual);
- puts(" ");
- puthex((unsigned long)((unsigned long)residual + sizeof(RESIDUAL)));
- puts("\n");
- puts("relocated to: ");
- puthex((unsigned long)hold_residual);
- puts(" ");
- puthex((unsigned long)((unsigned long)hold_residual + sizeof(RESIDUAL)));
- puts("\n");
- }
-
- /* we have to subtract 0x10000 here to correct for objdump including the
- size of the elf header which we strip -- Cort */
- zimage_start = (char *)(load_addr - 0x10000 + ZIMAGE_OFFSET);
- zimage_size = ZIMAGE_SIZE;
-
- if ( INITRD_OFFSET )
- initrd_start = load_addr - 0x10000 + INITRD_OFFSET;
- else
- initrd_start = 0;
- initrd_end = INITRD_SIZE + initrd_start;
-
- /*
- * Find a place to stick the zimage and initrd and
- * relocate them if we have to. -- Cort
- */
- avail_ram = (char *)PAGE_ALIGN((unsigned long)_end);
- puts("zimage at: "); puthex((unsigned long)zimage_start);
- puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); puts("\n");
- if ( (unsigned long)zimage_start <= 0x00800000 )
- {
- memcpy( (void *)avail_ram, (void *)zimage_start, zimage_size );
- zimage_start = (char *)avail_ram;
- puts("relocated to: "); puthex((unsigned long)zimage_start);
- puts(" ");
- puthex((unsigned long)zimage_size+(unsigned long)zimage_start);
- puts("\n");
- avail_ram += zimage_size;
- }
-
- /* relocate initrd */
- if ( initrd_start )
- {
- puts("initrd at: "); puthex(initrd_start);
- puts(" "); puthex(initrd_end); puts("\n");
- if ( (unsigned long)initrd_start <= 0x00800000 )
- {
- memcpy( (void *)avail_ram,
- (void *)initrd_start, initrd_end-initrd_start );
- puts("relocated to: ");
- initrd_end = (unsigned long) avail_ram + (initrd_end-initrd_start);
- initrd_start = (unsigned long)avail_ram;
- puthex((unsigned long)initrd_start);
- puts(" ");
- puthex((unsigned long)initrd_end);
- puts("\n");
- }
- avail_ram = (char *)PAGE_ALIGN((unsigned long)initrd_end);
- }
-
- avail_ram = (char *)0x00400000;
- end_avail = (char *)0x00800000;
- puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" ");
- puthex((unsigned long)end_avail); puts("\n");
-
- if (keyb_present)
- CRT_tstc(); /* Forces keyboard to be initialized */
-
- puts("\nLinux/PPC load: ");
- timer = 0;
- cp = cmd_line;
- memcpy (cmd_line, cmd_preset, sizeof(cmd_preset));
- while ( *cp ) putc(*cp++);
- while (timer++ < 5*1000) {
- if (tstc()) {
- while ((ch = getc()) != '\n' && ch != '\r') {
- if (ch == '\b') {
- if (cp != cmd_line) {
- cp--;
- puts("\b \b");
- }
- } else {
- *cp++ = ch;
- putc(ch);
- }
- }
- break; /* Exit 'timer' loop */
- }
- udelay(1000); /* 1 msec */
- }
- *cp = 0;
- puts("\n");
-
- puts("Uncompressing Linux...");
- gunzip(0, 0x400000, zimage_start, &zimage_size);
- puts("done.\n");
-
- {
- struct bi_record *rec;
-
- rec = (struct bi_record *)PAGE_ALIGN(zimage_size);
-
- rec->tag = BI_FIRST;
- rec->size = sizeof(struct bi_record);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
- rec->tag = BI_BOOTLOADER_ID;
- memcpy( (void *)rec->data, "prepboot", 9);
- rec->size = sizeof(struct bi_record) + 8 + 1;
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
- rec->tag = BI_MACHTYPE;
- rec->data[0] = _MACH_prep;
- rec->data[1] = 1;
- rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
- rec->tag = BI_CMD_LINE;
- memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1);
- rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1;
- rec = (struct bi_record *)((ulong)rec + rec->size);
-
- rec->tag = BI_LAST;
- rec->size = sizeof(struct bi_record);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
- }
- puts("Now booting the kernel\n");
- return (unsigned long)hold_residual;
-}
-
-void puthex(unsigned long val)
-{
- unsigned char buf[10];
- int i;
- for (i = 7; i >= 0; i--)
- {
- buf[i] = "0123456789ABCDEF"[val & 0x0F];
- val >>= 4;
- }
- buf[8] = '\0';
- puts(buf);
-}
-
-/*
- * PCI/ISA I/O support
- */
-
-volatile unsigned char *ISA_io = (unsigned char *)0x80000000;
-volatile unsigned char *ISA_mem = (unsigned char *)0xC0000000;
-
-void
-outb(int port, char val)
-{
- /* Ensure I/O operations complete */
- __asm__ volatile("eieio");
- ISA_io[port] = val;
-}
-
-unsigned char
-inb(int port)
-{
- /* Ensure I/O operations complete */
- __asm__ volatile("eieio");
- return (ISA_io[port]);
-}
-
-unsigned long
-local_to_PCI(unsigned long addr)
-{
- return ((addr & 0x7FFFFFFF) | 0x80000000);
-}
-
-void
-_bcopy(char *src, char *dst, int len)
-{
- while (len--) *dst++ = *src++;
-}
-
-
-#define FALSE 0
-#define TRUE 1
-#include <stdarg.h>
-
-int
-strlen(char *s)
-{
- int len = 0;
- while (*s++) len++;
- return len;
-}
-
-_printk(char const *fmt, ...)
-{
- int ret;
- va_list ap;
-
- va_start(ap, fmt);
- ret = _vprintk(putc, fmt, ap);
- va_end(ap);
- return (ret);
-}
-
-#define is_digit(c) ((c >= '0') && (c <= '9'))
-
-int
-_vprintk(putc, fmt0, ap)
-int (*putc)();
-const char *fmt0;
-va_list ap;
-{
- char c, sign, *cp;
- int left_prec, right_prec, zero_fill, length, pad, pad_on_right;
- char buf[32];
- long val;
- while (c = *fmt0++)
- {
- if (c == '%')
- {
- c = *fmt0++;
- left_prec = right_prec = pad_on_right = 0;
- if (c == '-')
- {
- c = *fmt0++;
- pad_on_right++;
- }
- if (c == '0')
- {
- zero_fill = TRUE;
- c = *fmt0++;
- } else
- {
- zero_fill = FALSE;
- }
- while (is_digit(c))
- {
- left_prec = (left_prec * 10) + (c - '0');
- c = *fmt0++;
- }
- if (c == '.')
- {
- c = *fmt0++;
- zero_fill++;
- while (is_digit(c))
- {
- right_prec = (right_prec * 10) + (c - '0');
- c = *fmt0++;
- }
- } else
- {
- right_prec = left_prec;
- }
- sign = '\0';
- switch (c)
- {
- case 'd':
- case 'x':
- case 'X':
- val = va_arg(ap, long);
- switch (c)
- {
- case 'd':
- if (val < 0)
- {
- sign = '-';
- val = -val;
- }
- length = _cvt(val, buf, 10, "0123456789");
- break;
- case 'x':
- length = _cvt(val, buf, 16, "0123456789abcdef");
- break;
- case 'X':
- length = _cvt(val, buf, 16, "0123456789ABCDEF");
- break;
- }
- cp = buf;
- break;
- case 's':
- cp = va_arg(ap, char *);
- length = strlen(cp);
- break;
- case 'c':
- c = va_arg(ap, long /*char*/);
- (*putc)(c);
- continue;
- default:
- (*putc)('?');
- }
- pad = left_prec - length;
- if (sign != '\0')
- {
- pad--;
- }
- if (zero_fill)
- {
- c = '0';
- if (sign != '\0')
- {
- (*putc)(sign);
- sign = '\0';
- }
- } else
- {
- c = ' ';
- }
- if (!pad_on_right)
- {
- while (pad-- > 0)
- {
- (*putc)(c);
- }
- }
- if (sign != '\0')
- {
- (*putc)(sign);
- }
- while (length-- > 0)
- {
- (*putc)(c = *cp++);
- if (c == '\n')
- {
- (*putc)('\r');
- }
- }
- if (pad_on_right)
- {
- while (pad-- > 0)
- {
- (*putc)(c);
- }
- }
- } else
- {
- (*putc)(c);
- if (c == '\n')
- {
- (*putc)('\r');
- }
- }
- }
-}
-
-int _cvt(unsigned long val, char *buf, long radix, char *digits)
-{
- char temp[80];
- char *cp = temp;
- int length = 0;
- if (val == 0)
- { /* Special case */
- *cp++ = '0';
- } else
- while (val)
- {
- *cp++ = digits[val % radix];
- val /= radix;
- }
- while (cp != temp)
- {
- *buf++ = *--cp;
- length++;
- }
- *buf = '\0';
- return (length);
-}
-
-_dump_buf_with_offset(unsigned char *p, int s, unsigned char *base)
-{
- int i, c;
- if ((unsigned int)s > (unsigned int)p)
- {
- s = (unsigned int)s - (unsigned int)p;
- }
- while (s > 0)
- {
- if (base)
- {
- _printk("%06X: ", (int)p - (int)base);
- } else
- {
- _printk("%06X: ", p);
- }
- for (i = 0; i < 16; i++)
- {
- if (i < s)
- {
- _printk("%02X", p[i] & 0xFF);
- } else
- {
- _printk(" ");
- }
- if ((i % 2) == 1) _printk(" ");
- if ((i % 8) == 7) _printk(" ");
- }
- _printk(" |");
- for (i = 0; i < 16; i++)
- {
- if (i < s)
- {
- c = p[i] & 0xFF;
- if ((c < 0x20) || (c >= 0x7F)) c = '.';
- } else
- {
- c = ' ';
- }
- _printk("%c", c);
- }
- _printk("|\n");
- s -= 16;
- p += 16;
- }
-}
-
-_dump_buf(unsigned char *p, int s)
-{
- _printk("\n");
- _dump_buf_with_offset(p, s, 0);
-}
+++ /dev/null
-/*
- * Makes a prep bootable image which can be dd'd onto
- * a disk device to make a bootdisk. Will take
- * as input a elf executable, strip off the header
- * and write out a boot image as:
- * 1) default - strips elf header
- * suitable as a network boot image
- * 2) -pbp - strips elf header and writes out prep boot partition image
- * cat or dd onto disk for booting
- * 3) -asm - strips elf header and writes out as asm data
- * useful for generating data for a compressed image
- * -- Cort
- *
- * Modified for x86 hosted builds by Matt Porter <porter@neta.com>
- */
-
-#include <unistd.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <errno.h>
-
-#define cpu_to_le32(x) le32_to_cpu((x))
-unsigned long le32_to_cpu(unsigned long x)
-{
- return (((x & 0x000000ffU) << 24) |
- ((x & 0x0000ff00U) << 8) |
- ((x & 0x00ff0000U) >> 8) |
- ((x & 0xff000000U) >> 24));
-}
-
-
-#define cpu_to_le16(x) le16_to_cpu((x))
-unsigned short le16_to_cpu(unsigned short x)
-{
- return (((x & 0x00ff) << 8) |
- ((x & 0xff00) >> 8));
-}
-
-#define cpu_to_be32(x) (x)
-#define be32_to_cpu(x) (x)
-#define cpu_to_be16(x) (x)
-#define be16_to_cpu(x) (x)
-
-/* size of read buffer */
-#define SIZE 0x1000
-
-
-typedef unsigned long dword_t;
-typedef unsigned short word_t;
-typedef unsigned char byte_t;
-typedef byte_t block_t[512];
-typedef byte_t page_t[4096];
-
-
-/*
- * Partition table entry
- * - from the PReP spec
- */
-typedef struct partition_entry {
- byte_t boot_indicator;
- byte_t starting_head;
- byte_t starting_sector;
- byte_t starting_cylinder;
-
- byte_t system_indicator;
- byte_t ending_head;
- byte_t ending_sector;
- byte_t ending_cylinder;
-
- dword_t beginning_sector;
- dword_t number_of_sectors;
-} partition_entry_t;
-
-#define BootActive 0x80
-#define SystemPrep 0x41
-
-void copy_image(int , int);
-void write_prep_partition(int , int );
-void write_asm_data( int in, int out );
-
-unsigned int elfhdr_size = 65536;
-
-int main(int argc, char *argv[])
-{
- int in_fd, out_fd;
- int argptr = 1;
- unsigned int prep = 0;
- unsigned int asmoutput = 0;
-
- if ( (argc < 3) || (argc > 4) )
- {
- fprintf(stderr, "usage: %s [-pbp] [-asm] <boot-file> <image>\n",argv[0]);
- exit(-1);
- }
-
- /* needs to handle args more elegantly -- but this is a small/simple program */
-
- /* check for -pbp */
- if ( !strcmp( argv[argptr], "-pbp" ) )
- {
- prep = 1;
- argptr++;
- }
-
- /* check for -asm */
- if ( !strcmp( argv[argptr], "-asm" ) )
- {
- asmoutput = 1;
- argptr++;
- }
-
- /* input file */
- if ( !strcmp( argv[argptr], "-" ) )
- in_fd = 0; /* stdin */
- else
- if ((in_fd = open( argv[argptr] , 0)) < 0)
- exit(-1);
- argptr++;
-
- /* output file */
- if ( !strcmp( argv[argptr], "-" ) )
- out_fd = 1; /* stdout */
- else
- if ((out_fd = creat( argv[argptr] , 0755)) < 0)
- exit(-1);
- argptr++;
-
- /* skip elf header in input file */
- /*if ( !prep )*/
- lseek(in_fd, elfhdr_size, SEEK_SET);
-
- /* write prep partition if necessary */
- if ( prep )
- write_prep_partition( in_fd, out_fd );
-
- /* write input image to bootimage */
- if ( asmoutput )
- write_asm_data( in_fd, out_fd );
- else
- copy_image(in_fd, out_fd);
-
- return 0;
-}
-
-void write_prep_partition(int in, int out)
-{
- unsigned char block[512];
- partition_entry_t *pe = (partition_entry_t *)&block[0x1BE];
- dword_t *entry = (dword_t *)&block[0];
- dword_t *length = (dword_t *)&block[sizeof(long)];
- struct stat info;
-
- if (fstat(in, &info) < 0)
- {
- fprintf(stderr,"info failed\n");
- exit(-1);
- }
-
- bzero( block, sizeof block );
-
- /* set entry point and boot image size skipping over elf header */
-#ifdef __i386__
- *entry = 0x400/*+65536*/;
- *length = info.st_size-elfhdr_size+0x400;
-#else
- *entry = cpu_to_le32(0x400/*+65536*/);
- *length = cpu_to_le32(info.st_size-elfhdr_size+0x400);
-#endif /* __i386__ */
-
- /* sets magic number for msdos partition (used by linux) */
- block[510] = 0x55;
- block[511] = 0xAA;
-
- /*
- * Build a "PReP" partition table entry in the boot record
- * - "PReP" may only look at the system_indicator
- */
- pe->boot_indicator = BootActive;
- pe->system_indicator = SystemPrep;
- /*
- * The first block of the diskette is used by this "boot record" which
- * actually contains the partition table. (The first block of the
- * partition contains the boot image, but I digress...) We'll set up
- * one partition on the diskette and it shall contain the rest of the
- * diskette.
- */
- pe->starting_head = 0; /* zero-based */
- pe->starting_sector = 2; /* one-based */
- pe->starting_cylinder = 0; /* zero-based */
- pe->ending_head = 1; /* assumes two heads */
- pe->ending_sector = 18; /* assumes 18 sectors/track */
- pe->ending_cylinder = 79; /* assumes 80 cylinders/diskette */
-
- /*
- * The "PReP" software ignores the above fields and just looks at
- * the next two.
- * - size of the diskette is (assumed to be)
- * (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette)
- * - unlike the above sector numbers, the beginning sector is zero-based!
- */
-#if 0
- pe->beginning_sector = cpu_to_le32(1);
-#else
- /* This has to be 0 on the PowerStack? */
-#ifdef __i386__
- pe->beginning_sector = 0;
-#else
- pe->beginning_sector = cpu_to_le32(0);
-#endif /* __i386__ */
-#endif
-
-#ifdef __i386__
- pe->number_of_sectors = 2*18*80-1;
-#else
- pe->number_of_sectors = cpu_to_le32(2*18*80-1);
-#endif /* __i386__ */
-
- write( out, block, sizeof(block) );
- write( out, entry, sizeof(*entry) );
- write( out, length, sizeof(*length) );
- /* set file position to 2nd sector where image will be written */
- lseek( out, 0x400, SEEK_SET );
-}
-
-
-
-void
-copy_image(int in, int out)
-{
- char buf[SIZE];
- int n;
-
- while ( (n = read(in, buf, SIZE)) > 0 )
- write(out, buf, n);
-}
-
-
-void
-write_asm_data( int in, int out )
-{
- int i, cnt, pos, len;
- unsigned int cksum, val;
- unsigned char *lp;
- unsigned char buf[SIZE];
- unsigned char str[256];
-
- write( out, "\t.data\n\t.globl input_data\ninput_data:\n",
- strlen( "\t.data\n\t.globl input_data\ninput_data:\n" ) );
- pos = 0;
- cksum = 0;
- while ((len = read(in, buf, sizeof(buf))) > 0)
- {
- cnt = 0;
- lp = (unsigned char *)buf;
- len = (len + 3) & ~3; /* Round up to longwords */
- for (i = 0; i < len; i += 4)
- {
- if (cnt == 0)
- {
- write( out, "\t.long\t", strlen( "\t.long\t" ) );
- }
- sprintf( str, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
- write( out, str, strlen(str) );
- val = *(unsigned long *)lp;
- cksum ^= val;
- lp += 4;
- if (++cnt == 4)
- {
- cnt = 0;
- sprintf( str, " # %x \n", pos+i-12);
- write( out, str, strlen(str) );
- } else
- {
- write( out, ",", 1 );
- }
- }
- if (cnt)
- {
- write( out, "0\n", 2 );
- }
- pos += len;
- }
- sprintf(str, "\t.globl input_len\ninput_len:\t.long\t0x%x\n", pos);
- write( out, str, strlen(str) );
-
- fprintf(stderr, "cksum = %x\n", cksum);
-}
+++ /dev/null
-/*
- *
- *
- *
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-
-
-#define SIZE 1024
-#define BLOCK_ALIGN(x) (((x)+SIZE-1)&(~(SIZE-1)))
-
-static void
-die(const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- fputc('\n', stderr);
- exit(1);
-}
-
-static void
-usage(void)
-{
- printf("Usage: mkbinimg <bootstrap> <kernel> <ramdisk> -o <binary>\n");
- exit(1);
-}
-
-static int
-copy_blocks(int ifd, int ofd, unsigned long *offset, unsigned long *size)
-{
- off_t cur;
- int amt;
- unsigned long len = 0;
- char buffer[SIZE];
-
- cur = lseek(ofd, 0, SEEK_CUR);
-
- if (cur % SIZE) {
- cur = BLOCK_ALIGN(cur);
- cur = lseek(ofd, cur, SEEK_SET);
- }
-
- *offset = (unsigned long) cur;
- while((amt = read(ifd, buffer, SIZE)) > 0) {
- write(ofd, buffer, amt);
- len += amt;
- }
- *size = len;
- return 0;
-}
-
-
-int
-main(int argc, char *argv[])
-{
- char *kernel, *loader, *rdimage = NULL;
- unsigned long ld_off, kern_off, rd_off;
- unsigned long ld_size, kern_size, rd_size;
- int fd, ofd, len;
- char buffer[500];
-
- if (argc < 5 && !strcmp(argv[argc-2], "-o"))
- usage();
-
- if (argc > 5)
- rdimage = argv[3];
-
- kernel = argv[2];
- loader = argv[1];
-
- ofd = open(argv[argc-1], (O_RDWR|O_CREAT), 0755);
- if (ofd < 0) {
- die("can't open %s: %s", argv[5], strerror(errno));
- }
-
- ld_off = kern_off = rd_off = 0;
- ld_size = kern_size = rd_size = 0;
- memset(buffer, 0, 500);
- len = 0;
-
- fd = open(loader, O_RDONLY);
- if (fd < 0)
- die("can't open loader: %s", strerror(errno));
-
- copy_blocks(fd, ofd, &ld_off, &ld_size);
- len = sprintf(buffer, "bootloader: %x %x\n", ld_off, ld_size);
- close(fd);
-
- fd = open(kernel, O_RDONLY);
- if (fd < 0)
- die("can't open kernel: %s", strerror(errno));
-
- copy_blocks(fd, ofd, &kern_off, &kern_size);
- len += sprintf(buffer+len, "zimage: %x %x\n", kern_off, kern_size);
- close(fd);
-
- if (rdimage) {
- fd = open(rdimage, O_RDONLY);
- if (fd < 0)
- die("can't get ramdisk: %s", strerror(errno));
-
- copy_blocks(fd, ofd, &rd_off, &rd_size);
- close(fd);
- }
-
- len += sprintf(buffer+len, "initrd: %x %x", rd_off, rd_size);
-
- close(ofd);
-
- printf("%s\n", buffer);
-
- return 0;
-}
-
+++ /dev/null
-/*
- * COM1 NS16550 support
- */
-
-#include "ns16550.h"
-typedef struct NS16550 *NS16550_t;
-
-const NS16550_t COM_PORTS[] = { (NS16550_t) COM1,
- (NS16550_t) COM2,
- (NS16550_t) COM3,
- (NS16550_t) COM4 };
-
-volatile struct NS16550 *
-NS16550_init(int chan)
-{
- volatile struct NS16550 *com_port;
- volatile unsigned char xx;
- com_port = (struct NS16550 *) COM_PORTS[chan];
- /* See if port is present */
- com_port->lcr = 0x00;
- com_port->ier = 0xFF;
-#if 0
- if (com_port->ier != 0x0F) return ((struct NS16550 *)0);
-#endif
- com_port->ier = 0x00;
- com_port->lcr = 0x80; /* Access baud rate */
- com_port->dll = 0xc; /* 9600 baud */
- com_port->dlm = 0xc >> 8;
- com_port->lcr = 0x03; /* 8 data, 1 stop, no parity */
- com_port->mcr = 0x03; /* RTS/DTR */
- com_port->fcr = 0x07; /* Clear & enable FIFOs */
- return (com_port);
-}
-
-
-NS16550_putc(volatile struct NS16550 *com_port, unsigned char c)
-{
- volatile int i;
- while ((com_port->lsr & LSR_THRE) == 0) ;
- com_port->thr = c;
-}
-
-unsigned char
-NS16550_getc(volatile struct NS16550 *com_port)
-{
- while ((com_port->lsr & LSR_DR) == 0) ;
- return (com_port->rbr);
-}
-
-NS16550_tstc(volatile struct NS16550 *com_port)
-{
- return ((com_port->lsr & LSR_DR) != 0);
-}
-
-
-
+++ /dev/null
-/*
- * NS16550 Serial Port
- */
-
-struct NS16550
- {
- unsigned char rbr; /* 0 */
- unsigned char ier; /* 1 */
- unsigned char fcr; /* 2 */
- unsigned char lcr; /* 3 */
- unsigned char mcr; /* 4 */
- unsigned char lsr; /* 5 */
- unsigned char msr; /* 6 */
- unsigned char scr; /* 7 */
- };
-
-#define thr rbr
-#define iir fcr
-#define dll rbr
-#define dlm ier
-
-#define LSR_DR 0x01 /* Data ready */
-#define LSR_OE 0x02 /* Overrun */
-#define LSR_PE 0x04 /* Parity error */
-#define LSR_FE 0x08 /* Framing error */
-#define LSR_BI 0x10 /* Break */
-#define LSR_THRE 0x20 /* Xmit holding register empty */
-#define LSR_TEMT 0x40 /* Xmitter empty */
-#define LSR_ERR 0x80 /* Error */
-
-#define COM1 0x800003F8
-#define COM2 0x800002F8
-#define COM3 0x800003F8
-#define COM4 0x80000388
+++ /dev/null
-/* Open Firmware Client Interface */
-
-
-#include "of1275.h"
-
-
-static int (*of_server)(void *) = (int(*)(void*))-1;
-
-void
-of_init(void *handler)
-{
- of_server = (int(*)(void*))handler;
-}
-
-
-/* 6.3.2.1 Client interface */
-
-
-int
-of_test(const char *name, int *missing)
-{
- int result;
- static of_test_service s;
- s.service = "test";
- s.n_args = 1;
- s.n_returns = 1;
- s.name = name;
- result = of_server(&s);
- *missing = s.missing;
- return result;
-}
-
-
-/* 6.3.2.2 Device tree */
-
-
-int
-of_peer(int phandle, int *sibling_phandle)
-{
- int result;
- static of_peer_service s;
- s.service = "peer";
- s.n_args = 1;
- s.n_returns = 1;
- s.phandle = phandle;
- result = of_server(&s);
- *sibling_phandle = s.sibling_phandle;
- return result;
-}
-
-int
-of_child(int phandle, int *child_phandle)
-{
- int result;
- static of_child_service s;
- s.service = "child";
- s.n_args = 1;
- s.n_returns = 1;
- s.phandle = phandle;
- result = of_server(&s);
- *child_phandle = s.child_phandle;
- return result;
-}
-
-int
-of_parent(int phandle, int *parent_phandle)
-{
- int result;
- static of_parent_service s;
- s.service = "parent";
- s.n_args = 1;
- s.n_returns = 1;
- s.phandle = phandle;
- result = of_server(&s);
- *parent_phandle = s.parent_phandle;
- return result;
-}
-
-int
-of_instance_to_package(int ihandle, int *phandle)
-{
- int result;
- static of_instance_to_package_service s;
- s.service = "instance-to-package";
- s.n_args = 1;
- s.n_returns = 1;
- s.ihandle = ihandle;
- result = of_server(&s);
- *phandle = s.phandle;
- return result;
-}
-
-int
-of_getproplen(int phandle, const char *name, int *proplen)
-{
- int result;
- static of_getproplen_service s;
- s.service = "getproplen";
- s.n_args = 2;
- s.n_returns = 1;
- s.phandle = phandle;
- s.name = name;
- result = of_server(&s);
- *proplen = s.proplen;
- return result;
-}
-
-int
-of_getprop(int phandle, const char *name, void *buf, int buflen, int *size)
-{
- int result;
- static of_getprop_service s;
- s.service = "getprop";
- s.n_args = 4;
- s.n_returns = 1;
- s.phandle = phandle;
- s.name = name;
- s.buf = buf;
- s.buflen = buflen;
- result = of_server(&s);
- *size = s.size;
- return result;
-}
-
-int
-of_nextprop(int phandle, const char *previous, void *buf, int *flag)
-{
- int result;
- static of_nextprop_service s;
- s.service = "nextprop";
- s.n_args = 3;
- s.n_returns = 1;
- s.phandle = phandle;
- s.previous = previous;
- s.buf = buf;
- result = of_server(&s);
- *flag = s.flag;
- return result;
-}
-
-int
-of_setprop(int phandle, const char *name, void *buf, int len, int *size)
-{
- int result;
- static of_setprop_service s;
- s.service = "setprop";
- s.n_args = 4;
- s.n_returns = 1;
- s.phandle = phandle;
- s.name = name;
- s.buf = buf;
- s.len = len;
- result = of_server(&s);
- *size = s.size;
- return result;
-}
-
-int
-of_canon(const char *device_specifier, void *buf, int buflen, int *length)
-{
- int result;
- static of_canon_service s;
- s.service = "canon";
- s.n_args = 3;
- s.n_returns = 1;
- s.device_specifier = device_specifier;
- s.buf = buf;
- s.buflen = buflen;
- result = of_server(&s);
- *length = s.length;
- return result;
-}
-
-int
-of_finddevice(const char *device_specifier, int *phandle)
-{
- int result;
- static of_finddevice_service s;
- s.service = "finddevice";
- s.n_args = 1;
- s.n_returns = 1;
- s.device_specifier = device_specifier;
- result = of_server(&s);
- *phandle = s.phandle;
- return result;
-}
-
-int
-of_instance_to_path(int ihandle, void *buf, int buflen, int *length)
-{
- int result;
- static of_instance_to_path_service s;
- s.service = "instance-to-path";
- s.n_args = 3;
- s.n_returns = 1;
- s.ihandle = ihandle;
- s.buf = buf;
- s.buflen = buflen;
- result = of_server(&s);
- *length = s.length;
- return result;
-}
-
-int
-of_package_to_path(int phandle, void *buf, int buflen, int *length)
-{
- int result;
- static of_package_to_path_service s;
- s.service = "package-to-path";
- s.n_args = 3;
- s.n_returns = 1;
- s.phandle = phandle;
- s.buf = buf;
- s.buflen = buflen;
- result = of_server(&s);
- *length = s.length;
- return result;
-}
-
-/* int of_call_method(const char *method, int ihandle, ...); */
-
-
-/* 6.3.2.3 Device I/O */
-
-
-int
-of_open(const char *device_specifier, int *ihandle)
-{
- int result;
- static of_open_service s;
- s.service = "open";
- s.n_args = 1;
- s.n_returns = 1;
- s.device_specifier = device_specifier;
- result = of_server(&s);
- *ihandle = s.ihandle;
- return result;
-}
-
-int
-of_close(int ihandle)
-{
- int result;
- static of_close_service s;
- s.service = "close";
- s.n_args = 1;
- s.n_returns = 0;
- s.ihandle = ihandle;
- result = of_server(&s);
- return result;
-}
-
-int
-of_read(int ihandle, void *addr, int len, int *actual)
-{
- int result;
- static of_read_service s;
- s.service = "read";
- s.n_args = 3;
- s.n_returns = 1;
- s.ihandle = ihandle;
- s.addr = addr;
- s.len = len;
- result = of_server(&s);
- *actual = s.actual;
- return result;
-}
-
-int
-of_write(int ihandle, void *addr, int len, int *actual)
-{
- int result;
- static of_write_service s;
- s.service = "write";
- s.n_args = 3;
- s.n_returns = 1;
- s.ihandle = ihandle;
- s.addr = addr;
- s.len = len;
- result = of_server(&s);
- *actual = s.actual;
- return result;
-}
-
-int
-of_seek(int ihandle, int pos_hi, int pos_lo, int *status)
-{
- int result;
- static of_seek_service s;
- s.service = "seek";
- s.n_args = 3;
- s.n_returns = 1;
- s.ihandle = ihandle;
- s.pos_hi = pos_hi;
- s.pos_lo = pos_lo;
- result = of_server(&s);
- *status = s.status;
- return result;
-}
-
-
-/* 6.3.2.4 Memory */
-
-
-int
-of_claim(void *virt, int size, int align, void **baseaddr)
-{
- int result;
- static of_claim_service s;
- s.service = "claim";
- s.n_args = 3;
- s.n_returns = 1;
- s.virt = virt;
- s.size = size;
- s.align = align;
- result = of_server(&s);
- *baseaddr = s.baseaddr;
- return result;
-}
-
-int
-of_release(void *virt, int size)
-{
- int result;
- static of_release_service s;
- s.service = "release";
- s.n_args = 2;
- s.n_returns = 0;
- s.virt = virt;
- s.size = size;
- result = of_server(&s);
- return result;
-}
-
-
-/* 6.3.2.5 Control transfer */
-
-
-int
-of_boot(const char *bootspec)
-{
- int result;
- static of_boot_service s;
- s.service = "boot";
- s.n_args = 1;
- s.n_returns = 0;
- s.bootspec = bootspec;
- result = of_server(&s);
- return result;
-}
-
-int
-of_enter(void)
-{
- int result;
- static of_enter_service s;
- s.service = "enter";
- s.n_args = 0;
- s.n_returns = 0;
- result = of_server(&s);
- return result;
-}
-
-int
-of_exit(void)
-{
- int result;
- static of_exit_service s;
- s.service = "exit";
- s.n_args = 0;
- s.n_returns = 0;
- result = of_server(&s);
- return result;
-}
-
-/* int of_chain(void *virt, int size, void *entry, void *args, int len); */
-
-
-/* 6.3.2.6 User interface */
-
-
-/* int of_interpret(const char *arg, ...); */
-
-int
-of_set_callback(void *newfunc, void **oldfunc)
-{
- int result;
- static of_set_callback_service s;
- s.service = "set-callback";
- s.n_args = 1;
- s.n_returns = 1;
- s.newfunc = newfunc;
- result = of_server(&s);
- *oldfunc = s.oldfunc;
- return result;
-}
-
-int
-of_set_symbol_lookup(void *sym_to_value, void *value_to_sym)
-{
- int result;
- static of_set_symbol_lookup_service s;
- s.service = "set-symbol-lookup";
- s.n_args = 2;
- s.n_returns = 0;
- s.sym_to_value = sym_to_value;
- s.value_to_sym = s.value_to_sym;
- result = of_server(&s);
- return result;
-}
-
-
-/* 6.3.2.7 Time */
-
-
-int
-of_milliseconds(int *ms)
-{
- int result;
- static of_milliseconds_service s;
- s.service = "milliseconds";
- s.n_args = 0;
- s.n_returns = 1;
- result = of_server(&s);
- *ms = s.ms;
- return result;
-}
+++ /dev/null
-/* 6.3.2.1 Client interface */
-
-
-typedef struct _of_test_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- const char *name;
- /*out*/
- int missing;
-} of_test_service;
-
-int of_test(const char *name, int *missing);
-
-
-/* 6.3.2.2 Device tree */
-
-
-typedef struct _of_peer_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- int phandle;
- /*out*/
- int sibling_phandle;
-} of_peer_service;
-
-int of_peer(int phandle, int *sibling_phandle);
-
-
-typedef struct _of_child_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- int phandle;
- /*out*/
- int child_phandle;
-} of_child_service;
-
-int of_child(int phandle, int *child_phandle);
-
-
-typedef struct _of_parent_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- int phandle;
- /*out*/
- int parent_phandle;
-} of_parent_service;
-
-int of_child(int phandle, int *parent_phandle);
-
-
-typedef struct _of_instance_to_package_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- int ihandle;
- /*out*/
- int phandle;
-} of_instance_to_package_service;
-
-int of_instance_to_package(int ihandle, int *phandle);
-
-
-typedef struct _of_getproplen_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- int phandle;
- const char *name;
- /*out*/
- int proplen;
-} of_getproplen_service;
-
-int of_getproplen(int phandle, const char *name, int *proplen);
-
-
-typedef struct _of_getprop_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- int phandle;
- const char *name;
- void *buf;
- int buflen;
- /*out*/
- int size;
-} of_getprop_service;
-
-int of_getprop(int phandle, const char *name, void *buf, int buflen,
- int *size);
-
-
-typedef struct _of_nextprop_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- int phandle;
- const char *previous;
- void *buf;
- /*out*/
- int flag;
-} of_nextprop_service;
-
-int of_nextprop(int phandle, const char *previous, void *buf, int *flag);
-
-
-typedef struct _of_setprop_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- int phandle;
- const char *name;
- void *buf;
- int len;
- /*out*/
- int size;
-} of_setprop_service;
-
-int of_setprop(int phandle, const char *name, void *buf, int len, int *size);
-
-
-typedef struct _of_canon_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- const char *device_specifier;
- void *buf;
- int buflen;
- /*out*/
- int length;
-} of_canon_service;
-
-int of_canon(const char *device_specifier, void *buf, int buflen, int *length);
-
-
-typedef struct _of_finddevice_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- const char *device_specifier;
- /*out*/
- int phandle;
-} of_finddevice_service;
-
-int of_finddevice(const char *device_specifier, int *phandle);
-
-
-typedef struct _of_instance_to_path_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- int ihandle;
- void *buf;
- int buflen;
- /*out*/
- int length;
-} of_instance_to_path_service;
-
-int of_instance_to_path(int ihandle, void *buf, int buflen, int *length);
-
-
-typedef struct _of_package_to_path_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- int phandle;
- void *buf;
- int buflen;
- /*out*/
- int length;
-} of_package_to_path_service;
-
-int of_package_to_path(int phandle, void *buf, int buflen, int *length);
-
-
-typedef struct _of_call_method_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- const char *method;
- int ihandle;
- /*...*/
- int args[0];
-} of_call_method_service;
-
-int of_call_method(const char *method, int ihandle, ...);
-
-
-/* 6.3.2.3 Device I/O */
-
-
-typedef struct _of_open_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- const char *device_specifier;
- /*out*/
- int ihandle;
-} of_open_service;
-
-int of_open(const char *device_specifier,
- int *ihandle);
-
-
-typedef struct _of_close_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- int ihandle;
- /*out*/
-} of_close_service;
-
-int of_close(int ihandle);
-
-
-typedef struct _of_read_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- int ihandle;
- void *addr;
- int len;
- /*out*/
- int actual;
-} of_read_service;
-
-int of_read(int ihandle, void *addr, int len, int *actual);
-
-
-typedef struct _of_write_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- int ihandle;
- void *addr;
- int len;
- /*out*/
- int actual;
-} of_write_service;
-
-int of_write(int ihandle, void *addr, int len, int *actual);
-
-
-typedef struct _of_seek_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- int ihandle;
- int pos_hi;
- int pos_lo;
- /*out*/
- int status;
-} of_seek_service;
-
-int of_seek(int ihandle, int pos_hi, int pos_lo, int *status);
-
-
-/* 6.3.2.4 Memory */
-
-
-typedef struct _of_claim_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- void *virt;
- int size;
- int align;
- /*out*/
- void *baseaddr;
-} of_claim_service;
-
-int of_claim(void *virt, int size, int align, void **baseaddr);
-
-
-typedef struct _of_release_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- void *virt;
- int size;
- int align;
- /*out*/
-} of_release_service;
-
-int of_release(void *virt, int size);
-
-
-/* 6.3.2.5 Control transfer */
-
-
-typedef struct _of_boot_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- const char *bootspec;
- /*out*/
-} of_boot_service;
-
-int of_boot(const char *bootspec);
-
-
-typedef struct _of_enter_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- /*out*/
-} of_enter_service;
-
-int of_enter(void);
-
-
-typedef struct _of_exit_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- /*out*/
-} of_exit_service;
-
-int of_exit(void);
-
-
-typedef struct _of_chain_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- void *virt;
- int size;
- void *entry;
- void *args;
- int len;
- /*out*/
-} of_chain_service;
-
-int of_chain(void *virt, int size, void *entry, void *args, int len);
-
-
-/* 6.3.2.6 User interface */
-
-
-typedef struct _of_interpret_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- const char *cmd;
- int args[0];
- /*...*/
- /*out*/
- /*...*/
-} of_interpret_service;
-
-int of_interpret(const char *arg, ...);
-
-
-typedef struct _of_set_callback_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- void *newfunc;
- /*out*/
- void *oldfunc;
-} of_set_callback_service;
-
-int of_set_callback(void *newfunc, void **oldfunc);
-
-
-typedef struct _of_set_symbol_lookup_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- void *sym_to_value;
- void *value_to_sym;
- /*out*/
-} of_set_symbol_lookup_service;
-
-int of_set_symbol_lookup(void *sym_to_value, void *value_to_sym);
-
-
-/* 6.3.2.7 Time */
-
-
-typedef struct _of_milliseconds_service {
- const char *service;
- int n_args;
- int n_returns;
- /*in*/
- /*out*/
- int ms;
-} of_milliseconds_service;
-
-int of_milliseconds(int *ms);
+++ /dev/null
-#!/bin/bash
-
-OFFSET=`$1 -h $2 | grep $3 | grep -v zvmlinux| awk '{print $6}'`
-echo "0x"$OFFSET
--- /dev/null
+# BK Id: SCCS/s.Makefile 1.8 05/21/01 09:10:38 trini
+#
+# Makefile for making XCOFF bootable images for booting on PowerMacs
+# using Open Firmware.
+#
+# Paul Mackerras January 1997
+#
+# Cleaned up, moved into arch/ppc/boot/pmac
+# Tom Rini January 2001
+
+OBJCOPY_ARGS = -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment
+COFF_LD_ARGS = -e _start -T ld.script -Ttext 500000 -Tdata 510000 -Bstatic
+CHRP_LD_ARGS = -Ttext 0x01000000
+
+COMMONOBJS = start.o misc.o ../common/string.o image.o
+COFFOBJS = ../common/coffcrt0.o $(COMMONOBJS) coffmain.o
+CHRPOBJS = ../common/crt0.o $(COMMONOBJS) chrpmain.o
+LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a
+
+MKNOTE := ../utils/mknote
+SIZE := ../utils/size
+OFFSET := ../utils/offset
+PIGGYBACK := ../utils/piggyback
+HACKCOFF := ../utils/hack-coff
+
+ifeq ($(CONFIG_PPC64BRIDGE),y)
+MSIZE=.64
+else
+MSIZE=
+endif
+
+ifeq ($(CONFIG_SMP),y)
+TFTPIMAGE=/tftpboot/zImage.pmac.smp$(MSIZE)
+else
+TFTPIMAGE=/tftpboot/zImage.pmac$(MSIZE)
+endif
+
+../common/crt0.o:
+ $(MAKE) -C ../common crt0.o
+
+../common/coffcrt0.o:
+ $(MAKE) -C ../common coffcrt0.o
+
+chrpmain.o: chrpmain.c
+ $(CC) $(CFLAGS) -DSYSMAP_OFFSET=0 -DSYSMAP_SIZE=0 -c chrpmain.c
+
+znetboot: vmlinux.coff vmlinux.elf-pmac zImage
+ cp ../images/vmlinux.coff $(TFTPIMAGE)
+ cp ../images/vmlinux.elf-pmac $(TFTPIMAGE).elf
+
+znetboot.initrd: vmlinux.coff.initrd vmlinux.initrd.elf-pmac
+ cp ../images/vmlinux.coff.initrd $(TFTPIMAGE)
+ cp ../images/vmlinux.elf-pmac.initrd $(TFTPIMAGE).elf
+
+#floppy: zImage
+# mount -t hfs /dev/fd0 /mnt
+# cp vmlinux.coff /mnt
+# umount /mnt
+
+miboot.image: dummy.o ../images/vmlinux.gz
+ $(OBJCOPY) $(OBJCOPY_ARGS) --add-section=image=../images/vmlinux.gz \
+ dummy.o ../images/$@
+
+miboot.image.initrd: miboot.image ../images/ramdisk.image.gz
+ $(OBJCOPY) $(OBJCOPY_ARGS) --add-section=initrd=../images/ramdisk.image.gz \
+ ../images/miboot.image ../images/$@
+
+coffboot: $(COFFOBJS) $(LIBS) ../common/no_initrd.o ld.script ../images/vmlinux.gz
+ $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) ../common/no_initrd.o $(LIBS)
+
+coffboot.initrd: $(COFFOBJS) $(LIBS) initrd.o ld.script ../images/vmlinux.gz
+ $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) initrd.o $(LIBS)
+
+image.o: $(PIGGYBACK) ../images/vmlinux.gz
+ $(PIGGYBACK) image < ../images/vmlinux.gz | $(AS) -o $@
+
+initrd.o: ../images/ramdisk.image.gz $(PIGGYBACK)
+ $(PIGGYBACK) initrd < ../images/ramdisk.image.gz | $(AS) -o $@
+
+vmlinux.coff: coffboot $(HACKCOFF)
+ $(OBJCOPY) $(OBJCOPY_ARGS) coffboot ../images/$@
+ $(HACKCOFF) ../images/$@
+ rm -f coffboot
+ ln -sf vmlinux.coff ../images/zImage.pmac
+
+vmlinux.coff.initrd: coffboot.initrd $(HACKCOFF)
+ $(OBJCOPY) $(OBJCOPY_ARGS) coffboot.initrd ../images/$@
+ $(HACKCOFF) ../images/$@
+ rm -f coffboot.initrd
+ ln -sf vmlinux.coff.initrd ../images/zImage.initrd.pmac
+
+vmlinux.elf-pmac: $(CHRPOBJS) $(LIBS) ../common/no_initrd.o $(MKNOTE) ../images/vmlinux.gz
+ $(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) ../common/no_initrd.o $(LIBS)
+ $(MKNOTE) > note
+ $(OBJCOPY) ../images/$@ ../images/$@ --add-section=.note=note \
+ --add-section=sysmap=$(TOPDIR)/System.map -R .comment
+ $(CC) $(CFLAGS) chrpmain.c -c -o chrpmain.o \
+ -DSYSMAP_OFFSET=`sh $(OFFSET) $(OBJDUMP) ../images/$@ sysmap` \
+ -DSYSMAP_SIZE=`sh $(SIZE) $(OBJDUMP) ../images/$@ sysmap`
+ $(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) ../common/no_initrd.o $(LIBS)
+ $(OBJCOPY) ../images/$@ ../images/$@ --add-section=.note=note \
+ --add-section=sysmap=$(TOPDIR)/System.map -R .comment
+ rm -f note
+
+vmlinux.initrd.elf-pmac: $(CHRPOBJS) $(LIBS) initrd.o $(MKNOTE) ../images/vmlinux.gz
+ $(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) initrd.o $(LIBS)
+ $(MKNOTE) > note
+ $(OBJCOPY) ../images/$@ ../images/$@ --add-section=.note=note -R .comment
+ rm -f note
+
+zImage: vmlinux.coff vmlinux.elf-pmac miboot.image
+
+zImage.initrd: vmlinux.coff.initrd vmlinux.initrd.elf-pmac miboot.image.initrd
+
+include $(TOPDIR)/Rules.make
--- /dev/null
+/*
+ * BK Id: SCCS/s.chrpmain.c 1.9 05/18/01 06:20:29 patch
+ */
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include "nonstdio.h"
+#include "zlib.h"
+#include <asm/bootinfo.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+
+extern void *finddevice(const char *);
+extern int getprop(void *, const char *, void *, int);
+extern void *claim(unsigned int, unsigned int, unsigned int);
+extern void release(void *ptr, unsigned int len);
+void make_bi_recs(unsigned long);
+void gunzip(void *, int, unsigned char *, int *);
+void stop_imac_ethernet(void);
+void stop_imac_usb(void);
+
+#define get_16be(x) (*(unsigned short *)(x))
+#define get_32be(x) (*(unsigned *)(x))
+
+#define RAM_END (16 << 20)
+
+#define PROG_START 0x00010000
+#define PROG_SIZE 0x003f0000
+
+#define SCRATCH_SIZE (128 << 10)
+
+#ifdef CONFIG_CMDLINE
+#define CMDLINE CONFIG_CMDLINE
+#else
+#define CMDLINE ""
+#endif
+char cmd_preset[] = CMDLINE;
+char cmd_buf[256];
+char *cmd_line = cmd_buf;
+
+char *avail_ram;
+char *begin_avail, *end_avail;
+char *avail_high;
+unsigned int heap_use;
+unsigned int heap_max;
+
+extern char _end[];
+extern char image_data[];
+extern int image_len;
+extern char initrd_data[];
+extern int initrd_len;
+
+
+boot(int a1, int a2, void *prom)
+{
+ int ns, oh, i;
+ unsigned sa, len;
+ void *dst;
+ unsigned char *im;
+ unsigned initrd_start, initrd_size;
+ extern char _start;
+
+ printf("chrpboot starting: loaded at 0x%x\n", &_start);
+ if (initrd_len) {
+ initrd_size = initrd_len;
+ initrd_start = (RAM_END - initrd_size) & ~0xFFF;
+ a1 = initrd_start;
+ a2 = initrd_size;
+ claim(initrd_start, RAM_END - initrd_start, 0);
+ printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n", initrd_start,
+ initrd_data,initrd_size);
+ memcpy((char *)initrd_start, initrd_data, initrd_size);
+ }
+ im = image_data;
+ len = image_len;
+ /* claim 3MB starting at PROG_START */
+ claim(PROG_START, PROG_SIZE, 0);
+ dst = (void *) PROG_START;
+ if (im[0] == 0x1f && im[1] == 0x8b) {
+ /* claim some memory for scratch space */
+ avail_ram = (char *) claim(0, SCRATCH_SIZE, 0x10);
+ begin_avail = avail_high = avail_ram;
+ end_avail = avail_ram + SCRATCH_SIZE;
+ printf("heap at 0x%x\n", avail_ram);
+ printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
+ gunzip(dst, PROG_SIZE, im, &len);
+ printf("done %u bytes\n", len);
+ printf("%u bytes of heap consumed, max in use %u\n",
+ avail_high - begin_avail, heap_max);
+ release(begin_avail, SCRATCH_SIZE);
+ } else {
+ memmove(dst, im, len);
+ }
+
+ flush_cache(dst, len);
+ memcpy (cmd_line, cmd_preset, sizeof(cmd_preset));
+ make_bi_recs((unsigned long) dst + len);
+
+ sa = (unsigned long)PROG_START;
+ printf("start address = 0x%x\n", sa);
+
+ (*(void (*)())sa)(a1, a2, prom);
+
+ printf("returned?\n");
+
+ pause();
+}
+
+void make_bi_recs(unsigned long addr)
+{
+ struct bi_record *rec;
+
+ /* leave a 1MB gap then align to the next 1MB boundary */
+ addr = _ALIGN(addr+ (1<<20) - 1, (1<<20));
+ if (addr >= PROG_START + PROG_SIZE)
+ claim(addr, 0x1000, 0);
+
+ rec = (struct bi_record *)addr;
+ rec->tag = BI_FIRST;
+ rec->size = sizeof(struct bi_record);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_BOOTLOADER_ID;
+ sprintf( (char *)rec->data, "coffboot");
+ rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1;
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_MACHTYPE;
+ rec->data[0] = _MACH_Pmac;
+ rec->data[1] = 1;
+ rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_CMD_LINE;
+ memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1);
+ rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1;
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+#ifdef SYSMAP_OFFSET
+ rec->tag = BI_SYSMAP;
+ rec->data[0] = SYSMAP_OFFSET;
+ rec->data[1] = SYSMAP_SIZE;
+ rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+#endif /* SYSMAP_OFFSET */
+
+ rec->tag = BI_LAST;
+ rec->size = sizeof(struct bi_record);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+}
+
+#if 0
+#define eieio() asm volatile("eieio");
+
+void stop_imac_ethernet(void)
+{
+ void *macio, *enet;
+ unsigned int macio_addr[5], enet_reg[6];
+ int len;
+ volatile unsigned int *dbdma;
+
+ macio = finddevice("/pci/mac-io");
+ enet = finddevice("/pci/mac-io/ethernet");
+ if (macio == NULL || enet == NULL)
+ return;
+ len = getprop(macio, "assigned-addresses", macio_addr, sizeof(macio_addr));
+ if (len != sizeof(macio_addr))
+ return;
+ len = getprop(enet, "reg", enet_reg, sizeof(enet_reg));
+ if (len != sizeof(enet_reg))
+ return;
+ printf("macio base %x, dma at %x & %x\n",
+ macio_addr[2], enet_reg[2], enet_reg[4]);
+
+ /* hope this is mapped... */
+ dbdma = (volatile unsigned int *) (macio_addr[2] + enet_reg[2]);
+ *dbdma = 0x80; /* clear the RUN bit */
+ eieio();
+ dbdma = (volatile unsigned int *) (macio_addr[2] + enet_reg[4]);
+ *dbdma = 0x80; /* clear the RUN bit */
+ eieio();
+}
+
+void stop_imac_usb(void)
+{
+ void *usb;
+ unsigned int usb_addr[5];
+ int len;
+ volatile unsigned int *usb_ctrl;
+
+ usb = finddevice("/pci/usb");
+ if (usb == NULL)
+ return;
+ len = getprop(usb, "assigned-addresses", usb_addr, sizeof(usb_addr));
+ if (len != sizeof(usb_addr))
+ return;
+ printf("usb base %x\n", usb_addr[2]);
+
+ usb_ctrl = (volatile unsigned int *) (usb_addr[2] + 8);
+ *usb_ctrl = 0x01000000; /* cpu_to_le32(1) */
+ eieio();
+}
+#endif
+
+struct memchunk {
+ unsigned int size;
+ struct memchunk *next;
+};
+
+static struct memchunk *freechunks;
+
+void *zalloc(void *x, unsigned items, unsigned size)
+{
+ void *p;
+ struct memchunk **mpp, *mp;
+
+ size *= items;
+ size = (size + 7) & -8;
+ heap_use += size;
+ if (heap_use > heap_max)
+ heap_max = heap_use;
+ for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
+ if (mp->size == size) {
+ *mpp = mp->next;
+ return mp;
+ }
+ }
+ p = avail_ram;
+ avail_ram += size;
+ if (avail_ram > avail_high)
+ avail_high = avail_ram;
+ if (avail_ram > end_avail) {
+ printf("oops... out of memory\n");
+ pause();
+ }
+ return p;
+}
+
+void zfree(void *x, void *addr, unsigned nb)
+{
+ struct memchunk *mp = addr;
+
+ nb = (nb + 7) & -8;
+ heap_use -= nb;
+ if (avail_ram == addr + nb) {
+ avail_ram = addr;
+ return;
+ }
+ mp->size = nb;
+ mp->next = freechunks;
+ freechunks = mp;
+}
+
+#define HEAD_CRC 2
+#define EXTRA_FIELD 4
+#define ORIG_NAME 8
+#define COMMENT 0x10
+#define RESERVED 0xe0
+
+#define DEFLATED 8
+
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+ z_stream s;
+ int r, i, flags;
+
+ /* skip header */
+ i = 10;
+ flags = src[3];
+ if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+ printf("bad gzipped data\n");
+ exit();
+ }
+ if ((flags & EXTRA_FIELD) != 0)
+ i = 12 + src[10] + (src[11] << 8);
+ if ((flags & ORIG_NAME) != 0)
+ while (src[i++] != 0)
+ ;
+ if ((flags & COMMENT) != 0)
+ while (src[i++] != 0)
+ ;
+ if ((flags & HEAD_CRC) != 0)
+ i += 2;
+ if (i >= *lenp) {
+ printf("gunzip: ran out of data in header\n");
+ exit();
+ }
+
+ s.zalloc = zalloc;
+ s.zfree = zfree;
+ r = inflateInit2(&s, -MAX_WBITS);
+ if (r != Z_OK) {
+ printf("inflateInit2 returned %d\n", r);
+ exit();
+ }
+ s.next_in = src + i;
+ s.avail_in = *lenp - i;
+ s.next_out = dst;
+ s.avail_out = dstlen;
+ r = inflate(&s, Z_FINISH);
+ if (r != Z_OK && r != Z_STREAM_END) {
+ printf("inflate returned %d msg: %s\n", r, s.msg);
+ exit();
+ }
+ *lenp = s.next_out - (unsigned char *) dst;
+ inflateEnd(&s);
+}
--- /dev/null
+/*
+ * BK Id: SCCS/s.coffmain.c 1.9 05/18/01 06:20:29 patch
+ */
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include "nonstdio.h"
+#include "zlib.h"
+#include <asm/bootinfo.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+
+extern void *finddevice(const char *);
+extern int getprop(void *, const char *, void *, int);
+extern char *claim(unsigned, unsigned, unsigned);
+void make_bi_recs(unsigned long);
+void gunzip(void *, int, unsigned char *, int *);
+
+#define get_16be(x) (*(unsigned short *)(x))
+#define get_32be(x) (*(unsigned *)(x))
+
+#define RAM_START 0xc0000000
+#define RAM_END (RAM_START + 0x800000) /* only 8M mapped with BATs */
+
+#define PROG_START RAM_START
+#define PROG_SIZE 0x00400000
+
+#define SCRATCH_SIZE (128 << 10)
+
+#ifdef CONFIG_CMDLINE
+#define CMDLINE CONFIG_CMDLINE
+#else
+#define CMDLINE ""
+#endif
+char cmd_preset[] = CMDLINE;
+char cmd_buf[256];
+char *cmd_line = cmd_buf;
+
+char *avail_ram;
+char *begin_avail, *end_avail;
+char *avail_high;
+unsigned int heap_use;
+unsigned int heap_max;
+
+extern char _start[], _end[];
+extern char image_data[];
+extern int image_len;
+extern char initrd_data[];
+extern int initrd_len;
+
+char heap[SCRATCH_SIZE];
+
+boot(int a1, int a2, void *prom)
+{
+ int ns, oh, i;
+ unsigned sa, len;
+ void *dst;
+ unsigned char *im;
+ unsigned initrd_start, initrd_size;
+
+ printf("coffboot starting: loaded at 0x%x\n", _start);
+ setup_bats(RAM_START);
+ if (initrd_len) {
+ initrd_size = initrd_len;
+ initrd_start = (RAM_END - initrd_size) & ~0xFFF;
+ a1 = initrd_start;
+ a2 = initrd_size;
+ claim(initrd_start - RAM_START, RAM_END - initrd_start, 0);
+ printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n",
+ initrd_start, initrd_data, initrd_size);
+ memcpy((char *)initrd_start, initrd_data, initrd_size);
+ }
+ im = image_data;
+ len = image_len;
+ /* claim 3MB starting at 0 */
+ claim(0, PROG_SIZE, 0);
+ dst = (void *) RAM_START;
+ if (im[0] == 0x1f && im[1] == 0x8b) {
+ /* claim some memory for scratch space */
+ begin_avail = avail_high = avail_ram = heap;
+ end_avail = heap + sizeof(heap);
+ printf("heap at 0x%x\n", avail_ram);
+ printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
+ gunzip(dst, PROG_SIZE, im, &len);
+ printf("done %u bytes\n", len);
+ printf("%u bytes of heap consumed, max in use %u\n",
+ avail_high - begin_avail, heap_max);
+ } else {
+ memmove(dst, im, len);
+ }
+
+ flush_cache(dst, len);
+ memcpy (cmd_line, cmd_preset, sizeof(cmd_preset));
+ make_bi_recs((unsigned long)dst + len);
+
+ sa = (unsigned long)PROG_START;
+ printf("start address = 0x%x\n", sa);
+
+ (*(void (*)())sa)(a1, a2, prom);
+
+ printf("returned?\n");
+
+ pause();
+}
+
+void make_bi_recs(unsigned long addr)
+{
+ struct bi_record *rec;
+
+ addr = _ALIGN(addr+ (1<<20) - 1, (1<<20));
+#if 0
+ if (addr >= PROG_START + PROG_SIZE)
+ claim(addr, 0x1000, 0);
+#endif
+
+ rec = (struct bi_record *)addr;
+ rec->tag = BI_FIRST;
+ rec->size = sizeof(struct bi_record);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_BOOTLOADER_ID;
+ sprintf( (char *)rec->data, "coffboot");
+ rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1;
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_MACHTYPE;
+ rec->data[0] = _MACH_Pmac;
+ rec->data[1] = 1;
+ rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_CMD_LINE;
+ memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1);
+ rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1;
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_LAST;
+ rec->size = sizeof(struct bi_record);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+}
+
+struct memchunk {
+ unsigned int size;
+ struct memchunk *next;
+};
+
+static struct memchunk *freechunks;
+
+void *zalloc(void *x, unsigned items, unsigned size)
+{
+ void *p;
+ struct memchunk **mpp, *mp;
+
+ size *= items;
+ size = (size + 7) & -8;
+ heap_use += size;
+ if (heap_use > heap_max)
+ heap_max = heap_use;
+ for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
+ if (mp->size == size) {
+ *mpp = mp->next;
+ return mp;
+ }
+ }
+ p = avail_ram;
+ avail_ram += size;
+ if (avail_ram > avail_high)
+ avail_high = avail_ram;
+ if (avail_ram > end_avail) {
+ printf("oops... out of memory\n");
+ pause();
+ }
+ return p;
+}
+
+void zfree(void *x, void *addr, unsigned nb)
+{
+ struct memchunk *mp = addr;
+
+ nb = (nb + 7) & -8;
+ heap_use -= nb;
+ if (avail_ram == addr + nb) {
+ avail_ram = addr;
+ return;
+ }
+ mp->size = nb;
+ mp->next = freechunks;
+ freechunks = mp;
+}
+
+#define HEAD_CRC 2
+#define EXTRA_FIELD 4
+#define ORIG_NAME 8
+#define COMMENT 0x10
+#define RESERVED 0xe0
+
+#define DEFLATED 8
+
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+ z_stream s;
+ int r, i, flags;
+
+ /* skip header */
+ i = 10;
+ flags = src[3];
+ if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+ printf("bad gzipped data\n");
+ exit();
+ }
+ if ((flags & EXTRA_FIELD) != 0)
+ i = 12 + src[10] + (src[11] << 8);
+ if ((flags & ORIG_NAME) != 0)
+ while (src[i++] != 0)
+ ;
+ if ((flags & COMMENT) != 0)
+ while (src[i++] != 0)
+ ;
+ if ((flags & HEAD_CRC) != 0)
+ i += 2;
+ if (i >= *lenp) {
+ printf("gunzip: ran out of data in header\n");
+ exit();
+ }
+
+ s.zalloc = zalloc;
+ s.zfree = zfree;
+ r = inflateInit2(&s, -MAX_WBITS);
+ if (r != Z_OK) {
+ printf("inflateInit2 returned %d\n", r);
+ exit();
+ }
+ s.next_in = src + i;
+ s.avail_in = *lenp - i;
+ s.next_out = dst;
+ s.avail_out = dstlen;
+ r = inflate(&s, Z_FINISH);
+ if (r != Z_OK && r != Z_STREAM_END) {
+ printf("inflate returned %d msg: %s\n", r, s.msg);
+ exit();
+ }
+ *lenp = s.next_out - (unsigned char *) dst;
+ inflateEnd(&s);
+}
--- /dev/null
+/*
+ * BK Id: SCCS/s.dummy.c 1.6 05/18/01 15:17:15 cort
+ */
+int main(void)
+{
+ return 0;
+}
--- /dev/null
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) } =0
+ .plt : { *(.plt) }
+ .text :
+ {
+ *(.text)
+ *(.rodata)
+ *(.rodata1)
+ *(.got1)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+ _etext = .;
+ PROVIDE (etext = .);
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x0FFF) & 0xFFFFF000;
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.got.plt) *(.got)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
+
--- /dev/null
+/*
+ * BK Id: SCCS/s.misc.S 1.6 05/18/01 15:17:15 cort
+ */
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+ .text
+
+/*
+ * Use the BAT3 registers to map the 1st 8MB of RAM to
+ * the address given as the 1st argument.
+ */
+ .globl setup_bats
+setup_bats:
+ mfpvr 5
+ rlwinm 5,5,16,16,31 /* r3 = 1 for 601, 4 for 604 */
+ cmpi 0,5,1
+ li 0,0
+ bne 4f
+ mtibatl 3,0 /* invalidate BAT first */
+ ori 3,3,4 /* set up BAT registers for 601 */
+ li 4,0x7f
+ mtibatu 3,3
+ mtibatl 3,4
+ b 5f
+4: mtdbatu 3,0 /* invalidate BATs first */
+ mtibatu 3,0
+ ori 3,3,0xff /* set up BAT registers for 604 */
+ li 4,2
+ mtdbatl 3,4
+ mtdbatu 3,3
+ mtibatl 3,4
+ mtibatu 3,3
+5: sync
+ isync
+ blr
+
+/*
+ * Flush the dcache and invalidate the icache for a range of addresses.
+ *
+ * flush_cache(addr, len)
+ */
+ .global flush_cache
+flush_cache:
+ addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */
+ rlwinm. 4,4,27,5,31
+ mtctr 4
+ beqlr
+1: dcbf 0,3
+ icbi 0,3
+ addi 3,3,0x20
+ bdnz 1b
+ sync
+ isync
+ blr
--- /dev/null
+/*
+ * BK Id: SCCS/s.start.c 1.8 05/18/01 15:17:15 cort
+ */
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <stdarg.h>
+
+int (*prom)();
+
+void *chosen_handle;
+void *stdin;
+void *stdout;
+void *stderr;
+
+void exit(void);
+void *finddevice(const char *name);
+int getprop(void *phandle, const char *name, void *buf, int buflen);
+void printk(char *fmt, ...);
+
+void
+start(int a1, int a2, void *promptr)
+{
+ prom = (int (*)()) promptr;
+ chosen_handle = finddevice("/chosen");
+ if (chosen_handle == (void *) -1)
+ exit();
+ if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
+ exit();
+ stderr = stdout;
+ if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
+ exit();
+
+ boot(a1, a2, promptr);
+ for (;;)
+ exit();
+}
+
+int
+write(void *handle, void *ptr, int nb)
+{
+ struct prom_args {
+ char *service;
+ int nargs;
+ int nret;
+ void *ihandle;
+ void *addr;
+ int len;
+ int actual;
+ } args;
+
+ args.service = "write";
+ args.nargs = 3;
+ args.nret = 1;
+ args.ihandle = handle;
+ args.addr = ptr;
+ args.len = nb;
+ args.actual = -1;
+ (*prom)(&args);
+ return args.actual;
+}
+
+int writestring(void *f, char *ptr, int nb)
+{
+ int w = 0, i;
+ char *ret = "\r";
+
+ for (i = 0; i < nb; ++i) {
+ if (ptr[i] == '\n') {
+ if (i > w) {
+ write(f, ptr + w, i - w);
+ w = i;
+ }
+ write(f, ret, 1);
+ }
+ }
+ if (w < nb)
+ write(f, ptr + w, nb - w);
+ return nb;
+}
+
+int
+read(void *handle, void *ptr, int nb)
+{
+ struct prom_args {
+ char *service;
+ int nargs;
+ int nret;
+ void *ihandle;
+ void *addr;
+ int len;
+ int actual;
+ } args;
+
+ args.service = "read";
+ args.nargs = 3;
+ args.nret = 1;
+ args.ihandle = handle;
+ args.addr = ptr;
+ args.len = nb;
+ args.actual = -1;
+ (*prom)(&args);
+ return args.actual;
+}
+
+void
+exit()
+{
+ struct prom_args {
+ char *service;
+ } args;
+
+ for (;;) {
+ args.service = "exit";
+ (*prom)(&args);
+ }
+}
+
+void
+pause()
+{
+ struct prom_args {
+ char *service;
+ } args;
+
+ args.service = "enter";
+ (*prom)(&args);
+}
+
+void *
+finddevice(const char *name)
+{
+ struct prom_args {
+ char *service;
+ int nargs;
+ int nret;
+ const char *devspec;
+ void *phandle;
+ } args;
+
+ args.service = "finddevice";
+ args.nargs = 1;
+ args.nret = 1;
+ args.devspec = name;
+ args.phandle = (void *) -1;
+ (*prom)(&args);
+ return args.phandle;
+}
+
+void *
+claim(unsigned int virt, unsigned int size, unsigned int align)
+{
+ struct prom_args {
+ char *service;
+ int nargs;
+ int nret;
+ unsigned int virt;
+ unsigned int size;
+ unsigned int align;
+ void *ret;
+ } args;
+
+ args.service = "claim";
+ args.nargs = 3;
+ args.nret = 1;
+ args.virt = virt;
+ args.size = size;
+ args.align = align;
+ (*prom)(&args);
+ return args.ret;
+}
+
+void
+release(void *virt, unsigned int size)
+{
+ struct prom_args {
+ char *service;
+ int nargs;
+ int nret;
+ void *virt;
+ unsigned int size;
+ } args;
+
+ args.service = "release";
+ args.nargs = 2;
+ args.nret = 0;
+ args.virt = virt;
+ args.size = size;
+ (*prom)(&args);
+}
+
+int
+getprop(void *phandle, const char *name, void *buf, int buflen)
+{
+ struct prom_args {
+ char *service;
+ int nargs;
+ int nret;
+ void *phandle;
+ const char *name;
+ void *buf;
+ int buflen;
+ int size;
+ } args;
+
+ args.service = "getprop";
+ args.nargs = 4;
+ args.nret = 1;
+ args.phandle = phandle;
+ args.name = name;
+ args.buf = buf;
+ args.buflen = buflen;
+ args.size = -1;
+ (*prom)(&args);
+ return args.size;
+}
+
+int
+putc(int c, void *f)
+{
+ char ch = c;
+
+ return writestring(f, &ch, 1) == 1? c: -1;
+}
+
+int
+putchar(int c)
+{
+ return putc(c, stdout);
+}
+
+int
+fputs(char *str, void *f)
+{
+ int n = strlen(str);
+
+ return writestring(f, str, n) == n? 0: -1;
+}
+
+int
+readchar()
+{
+ char ch;
+
+ for (;;) {
+ switch (read(stdin, &ch, 1)) {
+ case 1:
+ return ch;
+ case -1:
+ printk("read(stdin) returned -1\n");
+ return -1;
+ }
+ }
+}
+
+static char line[256];
+static char *lineptr;
+static int lineleft;
+
+int
+getchar()
+{
+ int c;
+
+ if (lineleft == 0) {
+ lineptr = line;
+ for (;;) {
+ c = readchar();
+ if (c == -1 || c == 4)
+ break;
+ if (c == '\r' || c == '\n') {
+ *lineptr++ = '\n';
+ putchar('\n');
+ break;
+ }
+ switch (c) {
+ case 0177:
+ case '\b':
+ if (lineptr > line) {
+ putchar('\b');
+ putchar(' ');
+ putchar('\b');
+ --lineptr;
+ }
+ break;
+ case 'U' & 0x1F:
+ while (lineptr > line) {
+ putchar('\b');
+ putchar(' ');
+ putchar('\b');
+ --lineptr;
+ }
+ break;
+ default:
+ if (lineptr >= &line[sizeof(line) - 1])
+ putchar('\a');
+ else {
+ putchar(c);
+ *lineptr++ = c;
+ }
+ }
+ }
+ lineleft = lineptr - line;
+ lineptr = line;
+ }
+ if (lineleft == 0)
+ return -1;
+ --lineleft;
+ return *lineptr++;
+}
+
+extern int vsprintf(char *buf, const char *fmt, va_list args);
+static char sprint_buf[1024];
+
+void
+printk(char *fmt, ...)
+{
+ va_list args;
+ int n;
+
+ va_start(args, fmt);
+ n = vsprintf(sprint_buf, fmt, args);
+ va_end(args);
+ writestring(stdout, sprint_buf, n);
+}
+
+int
+printf(char *fmt, ...)
+{
+ va_list args;
+ int n;
+
+ va_start(args, fmt);
+ n = vsprintf(sprint_buf, fmt, args);
+ va_end(args);
+ writestring(stdout, sprint_buf, n);
+ return n;
+}
--- /dev/null
+# BK Id: SCCS/s.Makefile 1.15 05/21/01 11:51:32 trini
+#
+# arch/ppc/boot/Makefile
+#
+# 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.
+#
+# Tom Rini January 2001
+#
+# Originally:
+# arch/ppc/boot/Makefile
+# Copyright (C) 1994 by Linus Torvalds
+# Adapted for PowerPC by Gary Thomas
+# modified by Cort (cort@cs.nmt.edu)
+#
+
+.c.s:
+ $(CC) $(CFLAGS) -S -o $*.s $<
+.s.o:
+ $(AS) -o $*.o $<
+.c.o:
+ $(CC) $(CFLAGS) -c -o $*.o $<
+.S.s:
+ $(CPP) $(AFLAGS) -traditional -o $*.o $<
+.S.o:
+ $(CC) $(AFLAGS) -traditional -c -o $*.o $<
+
+ifeq ($(CONFIG_SMP),y)
+TFTPIMAGE=/tftpboot/zImage.prep.smp
+else
+TFTPIMAGE=/tftpboot/zImage.prep
+endif
+
+ZLINKFLAGS = -T $(TOPDIR)/arch/$(ARCH)/vmlinux.lds -Ttext 0x00800000
+OBJECTS := head.o misc.o vreset.o kbd.o ../common/misc-common.o \
+ ../common/string.o of1275.o
+OBJCOPY_ARGS = -O elf32-powerpc
+LIBS = ../lib/zlib.a
+
+ifeq ($(CONFIG_SERIAL_CONSOLE),y)
+OBJECTS += ns16550.o
+endif
+
+# Tools
+MKPREP := ../utils/mkprep
+SIZE := ../utils/size
+OFFSET := ../utils/offset
+
+all: zImage
+
+misc.o: misc.c
+ $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \
+ -DZIMAGE_SIZE=0 -c -o $@ $*.c
+
+ns16550.o: ../common/ns16550.c
+ $(CC) $(CFLAGS) -DIOOFFSET=0x80000000 -c -o $@ ../common/$*.c
+
+zvmlinux.initrd: zvmlinux ../images/vmlinux.gz
+ $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS)
+ $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
+ --add-section=initrd=../images/ramdisk.image.gz \
+ --add-section=image=../images/vmlinux.gz \
+ $@.tmp $@
+ $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ initrd` \
+ -DINITRD_SIZE=`sh $(SIZE) $(OBJDUMP) $@ initrd` \
+ -DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ image` \
+ -DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) $@ image` \
+ -c -o misc.o misc.c
+ $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS)
+ $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
+ --add-section=initrd=../images/ramdisk.image.gz \
+ --add-section=image=../images/vmlinux.gz \
+ $@.tmp $@
+ rm -f $@.tmp zvmlinux
+
+zImage: zvmlinux $(MKPREP)
+ $(MKPREP) -pbp zvmlinux ../images/$@.prep
+ rm -f zvmlinux
+
+zImage.initrd: zvmlinux.initrd $(MKPREP)
+ $(MKPREP) -pbp zvmlinux.initrd ../images/$@.prep
+ rm -f zvmlinux.initrd
+
+zvmlinux: $(OBJECTS) $(LIBS) ../images/vmlinux.gz
+#
+# build the boot loader image and then compute the offset into it
+# for the kernel image
+#
+ $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS) $(LIBS)
+ $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
+ --add-section=image=../images/vmlinux.gz zvmlinux.tmp $@
+#
+# then with the offset rebuild the bootloader so we know where the kernel is
+#
+ $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \
+ -DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) zvmlinux image` \
+ -DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) zvmlinux image` \
+ -c -o misc.o misc.c
+ $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS) $(LIBS)
+ $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
+ --add-section=image=../images/vmlinux.gz $@.tmp $@
+ rm $@.tmp
+
+floppy: zImage
+ dd if=../images/zImage.prep of=/dev/fd0H1440 bs=64b
+
+znetboot : zImage
+ cp ../images/zImage.prep $(TFTPIMAGE)
+
+znetboot.initrd : zImage.initrd
+ cp ../images/zImage.initrd.prep $(TFTPIMAGE)
+
+include $(TOPDIR)/Rules.make
--- /dev/null
+/*
+ * BK Id: SCCS/s.head.S 1.8 05/18/01 06:20:29 patch
+ */
+#include "../../kernel/ppc_defs.h"
+#include "../../kernel/ppc_asm.tmpl"
+#include <asm/processor.h>
+#include <asm/cache.h>
+
+ .text
+
+/*
+ * Boot loader philosophy:
+ * ROM loads us to some arbitrary location
+ * Move the boot code to the link address (8M)
+ * Call decompress_kernel()
+ * Relocate the initrd, zimage and residual data to 8M
+ * Decompress the kernel to 0
+ * Jump to the kernel entry
+ * -- Cort
+ */
+ .globl start
+start:
+ bl start_
+start_:
+ mr r11,r3 /* Save pointer to residual/board data */
+ mr r25,r5 /* Save OFW pointer */
+ li r3,MSR_IP /* Establish default MSR value */
+ mtmsr r3
+
+/* check if we need to relocate ourselves to the link addr or were we
+ loaded there to begin with -- Cort */
+ lis r4,start@h
+ ori r4,r4,start@l
+ mflr r3
+ subi r3,r3,4 /* we get the nip, not the ip of the branch */
+ mr r8,r3
+ cmp 0,r3,r4
+ bne 1010f
+/* compute size of whole image in words. this should be moved to
+ * start_ldr() -- Cort
+ */
+ lis r4,start@h
+ ori r4,r4,start@l
+ lis r5,end@h
+ ori r5,r5,end@l
+ addi r5,r5,3 /* round up */
+ sub r5,r5,r4
+ srwi r5,r5,2
+ mr r7,r5
+ b start_ldr
+1010:
+/*
+ * no matter where we're loaded, move ourselves to -Ttext address
+ */
+relocate:
+ mflr r3 /* Compute code bias */
+ subi r3,r3,4
+ mr r8,r3
+ lis r4,start@h
+ ori r4,r4,start@l
+ lis r5,end@h
+ ori r5,r5,end@l
+ addi r5,r5,3 /* Round up - just in case */
+ sub r5,r5,r4 /* Compute # longwords to move */
+ srwi r5,r5,2
+ mtctr r5
+ mr r7,r5
+ li r6,0
+ subi r3,r3,4 /* Set up for loop */
+ subi r4,r4,4
+00: lwzu r5,4(r3)
+ stwu r5,4(r4)
+ xor r6,r6,r5
+ bdnz 00b
+ lis r3,start_ldr@h
+ ori r3,r3,start_ldr@l
+ mtlr r3 /* Easiest way to do an absolute jump */
+ blr
+start_ldr:
+/* Clear all of BSS */
+ lis r3,edata@h
+ ori r3,r3,edata@l
+ lis r4,end@h
+ ori r4,r4,end@l
+ subi r3,r3,4
+ subi r4,r4,4
+ li r0,0
+50: stwu r0,4(r3)
+ cmp 0,r3,r4
+ bne 50b
+90: mr r9,r1 /* Save old stack pointer (in case it matters) */
+ lis r1,.stack@h
+ ori r1,r1,.stack@l
+ addi r1,r1,4096*2
+ subi r1,r1,256
+ li r2,0x000F /* Mask pointer to 16-byte boundary */
+ andc r1,r1,r2
+/* Run loader */
+ mr r3,r8 /* Load point */
+ mr r4,r7 /* Program length */
+ mr r5,r6 /* Checksum */
+ mr r6,r11 /* Residual data */
+ mr r7,r25 /* OFW interfaces */
+ bl decompress_kernel
+
+ /* changed to use r3 (as firmware does) for kernel
+ as ptr to residual -- Cort*/
+ lis r6,cmd_line@h
+ ori r6,r6,cmd_line@l
+ lwz r6, 0(r6)
+ subi r7,r6,1
+00: lbzu r2,1(r7)
+ cmpi 0,r2,0
+ bne 00b
+
+ /* r4,r5 have initrd_start, size */
+ lis r2,initrd_start@h
+ ori r2,r2,initrd_start@l
+ lwz r4,0(r2)
+ lis r2,initrd_end@h
+ ori r2,r2,initrd_end@l
+ lwz r5,0(r2)
+
+
+ /* tell kernel we're prep */
+ /*
+ * get start address of kernel code which is stored as a coff
+ * entry. see boot/head.S -- Cort
+ */
+ li r9,0x4
+ mtlr r9
+ lis r10,0xdeadc0de@h
+ ori r10,r10,0xdeadc0de@l
+ li r9,0
+ stw r10,0(r9)
+/*
+ * The Radstone firmware maps PCI memory at 0xc0000000 using BAT2
+ * so disable BATs before setting this to avoid a clash
+ */
+ li r8,0
+ mtspr DBAT0U,r8
+ mtspr DBAT1U,r8
+ mtspr DBAT2U,r8
+ mtspr DBAT3U,r8
+ mtspr IBAT0U,r8
+ mtspr IBAT1U,r8
+ mtspr IBAT2U,r8
+ mtspr IBAT3U,r8
+
+ blr
+hang:
+ b hang
+
+/*
+ * Delay for a number of microseconds
+ * -- Use the BUS timer (assumes 66MHz)
+ */
+ .globl udelay
+udelay:
+ mfspr r4,PVR
+ srwi r4,r4,16
+ cmpi 0,r4,1 /* 601 ? */
+ bne .udelay_not_601
+00: li r0,86 /* Instructions / microsecond? */
+ mtctr r0
+10: addi r0,r0,0 /* NOP */
+ bdnz 10b
+ subic. r3,r3,1
+ bne 00b
+ blr
+
+.udelay_not_601:
+ mulli r4,r3,1000 /* nanoseconds */
+ addi r4,r4,59
+ li r5,60
+ divw r4,r4,r5 /* BUS ticks */
+1: mftbu r5
+ mftb r6
+ mftbu r7
+ cmp 0,r5,r7
+ bne 1b /* Get [synced] base time */
+ addc r9,r6,r4 /* Compute end time */
+ addze r8,r5
+2: mftbu r5
+ cmp 0,r5,r8
+ blt 2b
+ bgt 3f
+ mftb r6
+ cmp 0,r6,r9
+ blt 2b
+3: blr
+
+.globl _get_HID0
+_get_HID0:
+ mfspr r3,HID0
+ blr
+
+.globl _put_HID0
+_put_HID0:
+ mtspr HID0,r3
+ blr
+
+.globl _get_MSR
+_get_MSR:
+ mfmsr r3
+ blr
+
+.globl _put_MSR
+_put_MSR:
+ mtmsr r3
+ blr
+
+/*
+ * Flush instruction cache
+ * *** I'm really paranoid here!
+ */
+_GLOBAL(flush_instruction_cache)
+ mflr r5
+ bl flush_data_cache
+ mfspr r3,HID0 /* Caches are controlled by this register */
+ li r4,0
+ ori r4,r4,(HID0_ICE|HID0_ICFI)
+ or r3,r3,r4 /* Need to enable+invalidate to clear */
+ mtspr HID0,r3
+ andc r3,r3,r4
+ ori r3,r3,HID0_ICE /* Enable cache */
+ mtspr HID0,r3
+ mtlr r5
+ blr
+
+#define NUM_CACHE_LINES 128*8
+#define CACHE_LINE_SIZE 32
+#define cache_flush_buffer 0x1000
+
+/*
+ * Flush data cache
+ * *** I'm really paranoid here!
+ */
+_GLOBAL(flush_data_cache)
+ lis r3,cache_flush_buffer@h
+ ori r3,r3,cache_flush_buffer@l
+ li r4,NUM_CACHE_LINES
+ mtctr r4
+00: lwz r4,0(r3)
+ addi r3,r3,CACHE_LINE_SIZE /* Next line, please */
+ bdnz 00b
+10: blr
+ .comm .stack,4096*2,4
--- /dev/null
+/*
+ * BK Id: SCCS/s.iso_font.h 1.6 05/18/01 15:16:42 cort
+ */
+static const unsigned char font[] = {
+/* 0x00 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x01 */ 0x00,0x00,0x7E,0x81,0xA5,0x81,0x81,0xBD,0x99,0x81,0x81,0x7E,0x00,0x00,0x00,0x00,
+/* 0x02 */ 0x00,0x00,0x7E,0xFF,0xDB,0xFF,0xFF,0xC3,0xC3,0xE7,0xFF,0x7E,0x00,0x00,0x00,0x00,
+/* 0x03 */ 0x00,0x00,0x00,0x00,0x6C,0xFE,0xFE,0xFE,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00,
+/* 0x04 */ 0x00,0x00,0x00,0x00,0x10,0x38,0x7C,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00,0x00,
+/* 0x05 */ 0x00,0x00,0x00,0x18,0x3C,0x3C,0xE7,0xE7,0xE7,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0x06 */ 0x00,0x00,0x00,0x18,0x3C,0x7E,0xFF,0xFF,0x7E,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0x07 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x08 */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0xC3,0xC3,0xE7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+/* 0x09 */ 0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x42,0x42,0x66,0x3C,0x00,0x00,0x00,0x00,0x00,
+/* 0x0A */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xC3,0x99,0xBD,0xBD,0x99,0xC3,0xFF,0xFF,0xFF,0xFF,0xFF,
+/* 0x0B */ 0x00,0x00,0x3E,0x0E,0x1A,0x32,0x78,0xCC,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00,
+/* 0x0C */ 0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,
+/* 0x0D */ 0x00,0x00,0x30,0x38,0x3C,0x36,0x33,0x30,0x30,0x70,0xF0,0xE0,0x00,0x00,0x00,0x00,
+/* 0x0E */ 0x00,0x00,0x7F,0x63,0x7F,0x63,0x63,0x63,0x63,0x67,0xE7,0xE6,0xC0,0x00,0x00,0x00,
+/* 0x0F */ 0x00,0x00,0x00,0x18,0x18,0xDB,0x3C,0xE7,0x3C,0xDB,0x18,0x18,0x00,0x00,0x00,0x00,
+/* 0x10 */ 0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFE,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,
+/* 0x11 */ 0x00,0x02,0x06,0x0E,0x1E,0x3E,0xFE,0x3E,0x1E,0x0E,0x06,0x02,0x00,0x00,0x00,0x00,
+/* 0x12 */ 0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,
+/* 0x13 */ 0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00,
+/* 0x14 */ 0x00,0x00,0x7F,0xDB,0xDB,0xDB,0x7B,0x1B,0x1B,0x1B,0x1B,0x1B,0x00,0x00,0x00,0x00,
+/* 0x15 */ 0x00,0x7C,0xC6,0x60,0x38,0x6C,0xC6,0xC6,0x6C,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00,
+/* 0x16 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFE,0xFE,0x00,0x00,0x00,0x00,
+/* 0x17 */ 0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x7E,0x3C,0x18,0x7E,0x00,0x00,0x00,0x00,
+/* 0x18 */ 0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
+/* 0x19 */ 0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,
+/* 0x1A */ 0x00,0x00,0x00,0x00,0x00,0x18,0x0C,0xFE,0x0C,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x1B */ 0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xFE,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x1C */ 0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x1D */ 0x00,0x00,0x00,0x00,0x00,0x28,0x6C,0xFE,0x6C,0x28,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x1E */ 0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7C,0x7C,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,
+/* 0x1F */ 0x00,0x00,0x00,0x00,0xFE,0xFE,0x7C,0x7C,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00,
+/* 0x20 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x21 */ 0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
+/* 0x22 */ 0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x23 */ 0x00,0x00,0x00,0x6C,0x6C,0xFE,0x6C,0x6C,0x6C,0xFE,0x6C,0x6C,0x00,0x00,0x00,0x00,
+/* 0x24 */ 0x18,0x18,0x7C,0xC6,0xC2,0xC0,0x7C,0x06,0x06,0x86,0xC6,0x7C,0x18,0x18,0x00,0x00,
+/* 0x25 */ 0x00,0x00,0x00,0x00,0xC2,0xC6,0x0C,0x18,0x30,0x60,0xC6,0x86,0x00,0x00,0x00,0x00,
+/* 0x26 */ 0x00,0x00,0x38,0x6C,0x6C,0x38,0x76,0xDC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x27 */ 0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x28 */ 0x00,0x00,0x0C,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0C,0x00,0x00,0x00,0x00,
+/* 0x29 */ 0x00,0x00,0x30,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x30,0x00,0x00,0x00,0x00,
+/* 0x2A */ 0x00,0x00,0x00,0x00,0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x2B */ 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x2C */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00,
+/* 0x2D */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x2E */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
+/* 0x2F */ 0x00,0x00,0x00,0x00,0x02,0x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00,0x00,0x00,0x00,
+/* 0x30 */ 0x00,0x00,0x38,0x6C,0xC6,0xC6,0xD6,0xD6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00,
+/* 0x31 */ 0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00,
+/* 0x32 */ 0x00,0x00,0x7C,0xC6,0x06,0x0C,0x18,0x30,0x60,0xC0,0xC6,0xFE,0x00,0x00,0x00,0x00,
+/* 0x33 */ 0x00,0x00,0x7C,0xC6,0x06,0x06,0x3C,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x34 */ 0x00,0x00,0x0C,0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00,
+/* 0x35 */ 0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xFC,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x36 */ 0x00,0x00,0x38,0x60,0xC0,0xC0,0xFC,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x37 */ 0x00,0x00,0xFE,0xC6,0x06,0x06,0x0C,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,
+/* 0x38 */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x39 */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00,
+/* 0x3A */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
+/* 0x3B */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00,
+/* 0x3C */ 0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00,
+/* 0x3D */ 0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x3E */ 0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00,
+/* 0x3F */ 0x00,0x00,0x7C,0xC6,0xC6,0x0C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
+/* 0x40 */ 0x00,0x00,0x00,0x7C,0xC6,0xC6,0xDE,0xDE,0xDE,0xDC,0xC0,0x7C,0x00,0x00,0x00,0x00,
+/* 0x41 */ 0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+/* 0x42 */ 0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x66,0x66,0x66,0x66,0xFC,0x00,0x00,0x00,0x00,
+/* 0x43 */ 0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x00,0x00,0x00,0x00,
+/* 0x44 */ 0x00,0x00,0xF8,0x6C,0x66,0x66,0x66,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00,
+/* 0x45 */ 0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00,
+/* 0x46 */ 0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
+/* 0x47 */ 0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xDE,0xC6,0xC6,0x66,0x3A,0x00,0x00,0x00,0x00,
+/* 0x48 */ 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+/* 0x49 */ 0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0x4A */ 0x00,0x00,0x1E,0x0C,0x0C,0x0C,0x0C,0x0C,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00,
+/* 0x4B */ 0x00,0x00,0xE6,0x66,0x66,0x6C,0x78,0x78,0x6C,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,
+/* 0x4C */ 0x00,0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00,
+/* 0x4D */ 0x00,0x00,0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+/* 0x4E */ 0x00,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+/* 0x4F */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x50 */ 0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
+/* 0x51 */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xDE,0x7C,0x0C,0x0E,0x00,0x00,
+/* 0x52 */ 0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x6C,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,
+/* 0x53 */ 0x00,0x00,0x7C,0xC6,0xC6,0x60,0x38,0x0C,0x06,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x54 */ 0x00,0x00,0x7E,0x7E,0x5A,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0x55 */ 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x56 */ 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x10,0x00,0x00,0x00,0x00,
+/* 0x57 */ 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0xEE,0x6C,0x00,0x00,0x00,0x00,
+/* 0x58 */ 0x00,0x00,0xC6,0xC6,0x6C,0x7C,0x38,0x38,0x7C,0x6C,0xC6,0xC6,0x00,0x00,0x00,0x00,
+/* 0x59 */ 0x00,0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0x5A */ 0x00,0x00,0xFE,0xC6,0x86,0x0C,0x18,0x30,0x60,0xC2,0xC6,0xFE,0x00,0x00,0x00,0x00,
+/* 0x5B */ 0x00,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00,
+/* 0x5C */ 0x00,0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x06,0x02,0x00,0x00,0x00,0x00,
+/* 0x5D */ 0x00,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00,
+/* 0x5E */ 0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x5F */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,
+/* 0x60 */ 0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x61 */ 0x00,0x00,0x00,0x00,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x62 */ 0x00,0x00,0xE0,0x60,0x60,0x78,0x6C,0x66,0x66,0x66,0x66,0x7C,0x00,0x00,0x00,0x00,
+/* 0x63 */ 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x64 */ 0x00,0x00,0x1C,0x0C,0x0C,0x3C,0x6C,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x65 */ 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x66 */ 0x00,0x00,0x38,0x6C,0x64,0x60,0xF0,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
+/* 0x67 */ 0x00,0x00,0x00,0x00,0x00,0x3E,0x66,0x66,0x66,0x66,0x66,0x3E,0x06,0x66,0x3C,0x00,
+/* 0x68 */ 0x00,0x00,0xE0,0x60,0x60,0x6C,0x76,0x66,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,
+/* 0x69 */ 0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0x6A */ 0x00,0x00,0x06,0x06,0x00,0x0E,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00,
+/* 0x6B */ 0x00,0x00,0xE0,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0xE6,0x00,0x00,0x00,0x00,
+/* 0x6C */ 0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0x6D */ 0x00,0x00,0x00,0x00,0x00,0x6C,0xFE,0xD6,0xD6,0xD6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+/* 0x6E */ 0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
+/* 0x6F */ 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x70 */ 0x00,0x00,0x00,0x00,0x00,0xFC,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00,
+/* 0x71 */ 0x00,0x00,0x00,0x00,0x00,0x7E,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0x0C,0x1E,0x00,
+/* 0x72 */ 0x00,0x00,0x00,0x00,0x00,0xDC,0x76,0x66,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
+/* 0x73 */ 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0x60,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x74 */ 0x00,0x00,0x10,0x30,0x30,0xFC,0x30,0x30,0x30,0x30,0x36,0x1C,0x00,0x00,0x00,0x00,
+/* 0x75 */ 0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x76 */ 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0x00,0x00,
+/* 0x77 */ 0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0x6C,0x00,0x00,0x00,0x00,
+/* 0x78 */ 0x00,0x00,0x00,0x00,0x00,0xC6,0x6C,0x38,0x38,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,
+/* 0x79 */ 0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00,
+/* 0x7A */ 0x00,0x00,0x00,0x00,0x00,0xFE,0xCC,0x18,0x30,0x60,0xC6,0xFE,0x00,0x00,0x00,0x00,
+/* 0x7B */ 0x00,0x00,0x0E,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00,
+/* 0x7C */ 0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
+/* 0x7D */ 0x00,0x00,0x70,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00,
+/* 0x7E */ 0x00,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x7F */ 0x00,0x00,0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0x00,0x00,0x00,0x00,0x00,
+/* 0x80 */ 0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x0C,0x06,0x7C,0x00,0x00,
+/* 0x81 */ 0x00,0x00,0xCC,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x82 */ 0x00,0x0C,0x18,0x30,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x83 */ 0x00,0x10,0x38,0x6C,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x84 */ 0x00,0x00,0xCC,0x00,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x85 */ 0x00,0x60,0x30,0x18,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x86 */ 0x00,0x38,0x6C,0x38,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x87 */ 0x00,0x00,0x00,0x00,0x3C,0x66,0x60,0x60,0x66,0x3C,0x0C,0x06,0x3C,0x00,0x00,0x00,
+/* 0x88 */ 0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x89 */ 0x00,0x00,0xC6,0x00,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x8A */ 0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x8B */ 0x00,0x00,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0x8C */ 0x00,0x18,0x3C,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0x8D */ 0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0x8E */ 0x00,0xC6,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+/* 0x8F */ 0x38,0x6C,0x38,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+/* 0x90 */ 0x18,0x30,0x60,0x00,0xFE,0x66,0x60,0x7C,0x60,0x60,0x66,0xFE,0x00,0x00,0x00,0x00,
+/* 0x91 */ 0x00,0x00,0x00,0x00,0x00,0xCC,0x76,0x36,0x7E,0xD8,0xD8,0x6E,0x00,0x00,0x00,0x00,
+/* 0x92 */ 0x00,0x00,0x3E,0x6C,0xCC,0xCC,0xFE,0xCC,0xCC,0xCC,0xCC,0xCE,0x00,0x00,0x00,0x00,
+/* 0x93 */ 0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x94 */ 0x00,0x00,0xC6,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x95 */ 0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x96 */ 0x00,0x30,0x78,0xCC,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x97 */ 0x00,0x60,0x30,0x18,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x98 */ 0x00,0x00,0xC6,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0x78,0x00,
+/* 0x99 */ 0x00,0xC6,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x9A */ 0x00,0xC6,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x9B */ 0x00,0x18,0x18,0x3C,0x66,0x60,0x60,0x60,0x66,0x3C,0x18,0x18,0x00,0x00,0x00,0x00,
+/* 0x9C */ 0x00,0x38,0x6C,0x64,0x60,0xF8,0x60,0x60,0x60,0x60,0xE6,0xFC,0x00,0x00,0x00,0x00,
+/* 0x9D */ 0x00,0x00,0x66,0x66,0x3C,0x18,0x7E,0x18,0x7E,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
+/* 0x9E */ 0x00,0xF8,0xCC,0xCC,0xF8,0xC4,0xCC,0xDE,0xCC,0xCC,0xCC,0xC6,0x00,0x00,0x00,0x00,
+/* 0x9F */ 0x00,0x0E,0x1B,0x18,0x18,0x18,0x7E,0x18,0x18,0x18,0x18,0x18,0xD8,0x70,0x00,0x00,
+/* 0xA0 */ 0x00,0x18,0x30,0x60,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0xA1 */ 0x00,0x0C,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0xA2 */ 0x00,0x18,0x30,0x60,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0xA3 */ 0x00,0x18,0x30,0x60,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0xA4 */ 0x00,0x00,0x76,0xDC,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
+/* 0xA5 */ 0x76,0xDC,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+/* 0xA6 */ 0x00,0x3C,0x6C,0x6C,0x3E,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xA7 */ 0x00,0x38,0x6C,0x6C,0x38,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xA8 */ 0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0xC0,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0xA9 */ 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,
+/* 0xAA */ 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00,
+/* 0xAB */ 0x00,0xC0,0xC0,0xC2,0xC6,0xCC,0x18,0x30,0x60,0xDC,0x86,0x0C,0x18,0x3E,0x00,0x00,
+/* 0xAC */ 0x00,0xC0,0xC0,0xC2,0xC6,0xCC,0x18,0x30,0x66,0xCE,0x9E,0x3E,0x06,0x06,0x00,0x00,
+/* 0xAD */ 0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3C,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00,
+/* 0xAE */ 0x00,0x00,0x00,0x00,0x00,0x36,0x6C,0xD8,0x6C,0x36,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xAF */ 0x00,0x00,0x00,0x00,0x00,0xD8,0x6C,0x36,0x6C,0xD8,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xB0 */ 0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,
+/* 0xB1 */ 0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,
+/* 0xB2 */ 0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,
+/* 0xB3 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xB4 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xB5 */ 0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xB6 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xB7 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xB8 */ 0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xB9 */ 0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xBA */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xBB */ 0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xBC */ 0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xBD */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xBE */ 0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xBF */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xC0 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xC1 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xC2 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xC3 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xC4 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xC5 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xC6 */ 0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xC7 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xC8 */ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xC9 */ 0x00,0x00,0x00,0x00,0x00,0x3F,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xCA */ 0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xCB */ 0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xCC */ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xCD */ 0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xCE */ 0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xCF */ 0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xD0 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xD1 */ 0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xD2 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xD3 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xD4 */ 0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xD5 */ 0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xD6 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xD7 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xD8 */ 0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xD9 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xDA */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xDB */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+/* 0xDC */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+/* 0xDD */ 0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
+/* 0xDE */ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
+/* 0xDF */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xE0 */ 0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0xD8,0xD8,0xD8,0xDC,0x76,0x00,0x00,0x00,0x00,
+/* 0xE1 */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xFC,0xC6,0xC6,0xC6,0xC6,0xDC,0xC0,0xC0,0x00,0x00,
+/* 0xE2 */ 0x00,0x00,0xFE,0xC6,0xC6,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,
+/* 0xE3 */ 0x00,0x00,0x00,0x00,0x00,0xFE,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,
+/* 0xE4 */ 0x00,0x00,0xFE,0xC6,0x60,0x30,0x18,0x18,0x30,0x60,0xC6,0xFE,0x00,0x00,0x00,0x00,
+/* 0xE5 */ 0x00,0x00,0x00,0x00,0x00,0x7E,0xD8,0xD8,0xD8,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00,
+/* 0xE6 */ 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0xC0,0x00,0x00,0x00,
+/* 0xE7 */ 0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
+/* 0xE8 */ 0x00,0x00,0x7E,0x18,0x3C,0x66,0x66,0x66,0x66,0x3C,0x18,0x7E,0x00,0x00,0x00,0x00,
+/* 0xE9 */ 0x00,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00,
+/* 0xEA */ 0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0x6C,0x6C,0x6C,0x6C,0xEE,0x00,0x00,0x00,0x00,
+/* 0xEB */ 0x00,0x00,0x1E,0x30,0x18,0x0C,0x3E,0x66,0x66,0x66,0x66,0x3C,0x00,0x00,0x00,0x00,
+/* 0xEC */ 0x00,0x00,0x00,0x00,0x00,0x7E,0xDB,0xDB,0xDB,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xED */ 0x00,0x00,0x00,0x03,0x06,0x7E,0xDB,0xDB,0xF3,0x7E,0x60,0xC0,0x00,0x00,0x00,0x00,
+/* 0xEE */ 0x00,0x00,0x1C,0x30,0x60,0x60,0x7C,0x60,0x60,0x60,0x30,0x1C,0x00,0x00,0x00,0x00,
+/* 0xEF */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+/* 0xF0 */ 0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,
+/* 0xF1 */ 0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,
+/* 0xF2 */ 0x00,0x00,0x00,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00,0x7E,0x00,0x00,0x00,0x00,
+/* 0xF3 */ 0x00,0x00,0x00,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00,0x7E,0x00,0x00,0x00,0x00,
+/* 0xF4 */ 0x00,0x0E,0x1B,0x1B,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xF5 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xD8,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00,
+/* 0xF6 */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x7E,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
+/* 0xF7 */ 0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xF8 */ 0x00,0x38,0x6C,0x6C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xF9 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xFA */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xFB */ 0x00,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0xEC,0x6C,0x6C,0x3C,0x1C,0x00,0x00,0x00,0x00,
+/* 0xFC */ 0x00,0xD8,0x6C,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xFD */ 0x00,0x70,0xD8,0x30,0x60,0xC8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xFE */ 0x00,0x00,0x00,0x00,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x00,0x00,0x00,0x00,0x00,
+};
--- /dev/null
+/*
+ * BK Id: SCCS/s.kbd.c 1.7 05/18/01 06:20:29 patch
+ */
+#include <linux/keyboard.h>
+
+#include <../drivers/char/defkeymap.c> /* yeah I know it's bad -- Cort */
+
+
+unsigned char shfts, ctls, alts, caps;
+
+#define KBDATAP 0x60 /* kbd data port */
+#define KBSTATUSPORT 0x61 /* kbd status */
+#define KBSTATP 0x64 /* kbd status port */
+#define KBINRDY 0x01
+#define KBOUTRDY 0x02
+
+extern unsigned char inb(int port);
+extern void outb(int port, char val);
+extern void puts(const char *);
+extern void puthex(unsigned long val);
+extern void udelay(long x);
+
+static int kbd(int noblock)
+{
+ unsigned char dt, brk, val;
+ unsigned code;
+loop:
+ if (noblock) {
+ if ((inb(KBSTATP) & KBINRDY) == 0)
+ return (-1);
+ } else while((inb(KBSTATP) & KBINRDY) == 0) ;
+
+ dt = inb(KBDATAP);
+
+ brk = dt & 0x80; /* brk == 1 on key release */
+ dt = dt & 0x7f; /* keycode */
+
+ if (shfts)
+ code = shift_map[dt];
+ else if (ctls)
+ code = ctrl_map[dt];
+ else
+ code = plain_map[dt];
+
+ val = KVAL(code);
+ switch (KTYP(code) & 0x0f) {
+ case KT_LATIN:
+ if (brk)
+ break;
+ if (alts)
+ val |= 0x80;
+ if (val == 0x7f) /* map delete to backspace */
+ val = '\b';
+ return val;
+
+ case KT_LETTER:
+ if (brk)
+ break;
+ if (caps)
+ val -= 'a'-'A';
+ return val;
+
+ case KT_SPEC:
+ if (brk)
+ break;
+ if (val == KVAL(K_CAPS))
+ caps = !caps;
+ else if (val == KVAL(K_ENTER)) {
+enter: /* Wait for key up */
+ while (1) {
+ while((inb(KBSTATP) & KBINRDY) == 0) ;
+ dt = inb(KBDATAP);
+ if (dt & 0x80) /* key up */ break;
+ }
+ return 10;
+ }
+ break;
+
+ case KT_PAD:
+ if (brk)
+ break;
+ if (val < 10)
+ return val;
+ if (val == KVAL(K_PENTER))
+ goto enter;
+ break;
+
+ case KT_SHIFT:
+ switch (val) {
+ case KG_SHIFT:
+ case KG_SHIFTL:
+ case KG_SHIFTR:
+ shfts = brk ? 0 : 1;
+ break;
+ case KG_ALT:
+ case KG_ALTGR:
+ alts = brk ? 0 : 1;
+ break;
+ case KG_CTRL:
+ case KG_CTRLL:
+ case KG_CTRLR:
+ ctls = brk ? 0 : 1;
+ break;
+ }
+ break;
+
+ case KT_LOCK:
+ switch (val) {
+ case KG_SHIFT:
+ case KG_SHIFTL:
+ case KG_SHIFTR:
+ if (brk)
+ shfts = !shfts;
+ break;
+ case KG_ALT:
+ case KG_ALTGR:
+ if (brk)
+ alts = !alts;
+ break;
+ case KG_CTRL:
+ case KG_CTRLL:
+ case KG_CTRLR:
+ if (brk)
+ ctls = !ctls;
+ break;
+ }
+ break;
+ }
+ if (brk) return (-1); /* Ignore initial 'key up' codes */
+ goto loop;
+}
+
+static void kbdreset(void)
+{
+ unsigned char c;
+ int i;
+
+ /* flush input queue */
+ while ((inb(KBSTATP) & KBINRDY))
+ {
+ (void)inb(KBDATAP);
+ }
+ /* Send self-test */
+ while (inb(KBSTATP) & KBOUTRDY) ;
+ outb(KBSTATP,0xAA);
+ while ((inb(KBSTATP) & KBINRDY) == 0) ; /* wait input ready */
+ if ((c = inb(KBDATAP)) != 0x55)
+ {
+ puts("Keyboard self test failed - result:");
+ puthex(c);
+ puts("\n");
+ }
+ /* Enable interrupts and keyboard controller */
+ while (inb(KBSTATP) & KBOUTRDY) ;
+ outb(KBSTATP,0x60);
+ while (inb(KBSTATP) & KBOUTRDY) ;
+ outb(KBDATAP,0x45);
+ for (i = 0; i < 10000; i++) udelay(1);
+
+ while (inb(KBSTATP) & KBOUTRDY) ;
+ outb(KBSTATP,0x20);
+ while ((inb(KBSTATP) & KBINRDY) == 0) ; /* wait input ready */
+ if (! (inb(KBDATAP) & 0x40)) {
+ /*
+ * Quote from PS/2 System Reference Manual:
+ *
+ * "Address hex 0060 and address hex 0064 should be
+ * written only when the input-buffer-full bit and
+ * output-buffer-full bit in the Controller Status
+ * register are set 0." (KBINRDY and KBOUTRDY)
+ */
+
+ while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) ;
+ outb(KBDATAP,0xF0);
+ while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) ;
+ outb(KBDATAP,0x01);
+ }
+
+ while (inb(KBSTATP) & KBOUTRDY) ;
+ outb(KBSTATP,0xAE);
+}
+
+/* We have to actually read the keyboard when CRT_tstc is called,
+ * since the pending data might be a key release code, and therefore
+ * not valid data. In this case, kbd() will return -1, even though there's
+ * data to be read. Of course, we might actually read a valid key press,
+ * in which case it gets queued into key_pending for use by CRT_getc.
+ */
+
+static int kbd_reset = 0;
+
+static int key_pending = -1;
+
+int CRT_getc(void)
+{
+ int c;
+ if (!kbd_reset) {kbdreset(); kbd_reset++; }
+
+ if (key_pending != -1) {
+ c = key_pending;
+ key_pending = -1;
+ return c;
+ } else {
+ while ((c = kbd(0)) == 0) ;
+ return c;
+ }
+}
+
+int CRT_tstc(void)
+{
+ if (!kbd_reset) {kbdreset(); kbd_reset++; }
+
+ while (key_pending == -1 && ((inb(KBSTATP) & KBINRDY) != 0)) {
+ key_pending = kbd(1);
+ }
+
+ return (key_pending != -1);
+}
--- /dev/null
+/*
+ * BK Id: SCCS/s.misc.c 1.8 05/18/01 06:20:29 patch
+ */
+/*
+ * misc.c
+ *
+ * Adapted for PowerPC by Gary Thomas
+ *
+ * Rewritten by Cort Dougan (cort@cs.nmt.edu)
+ * One day to be replaced by a single bootloader for chrp/prep/pmac. -- Cort
+ */
+
+#include <linux/types.h>
+#include "zlib.h"
+#include <asm/residual.h>
+#include <linux/elf.h>
+#include <linux/config.h>
+#include <linux/pci_ids.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/bootinfo.h>
+#include <asm/mmu.h>
+#include <asm/byteorder.h>
+#if defined(CONFIG_SERIAL_CONSOLE)
+unsigned long com_port;
+#endif /* CONFIG_SERIAL_CONSOLE */
+
+/*
+ * Please send me load/board info and such data for hardware not
+ * listed here so I can keep track since things are getting tricky
+ * with the different load addrs with different firmware. This will
+ * help to avoid breaking the load/boot process.
+ * -- Cort
+ */
+char *avail_ram;
+char *end_avail;
+extern char _end[];
+
+#ifdef CONFIG_CMDLINE
+#define CMDLINE CONFIG_CMDLINE
+#else
+#define CMDLINE "";
+#endif
+char cmd_preset[] = CMDLINE;
+char cmd_buf[256];
+char *cmd_line = cmd_buf;
+
+int keyb_present = 1; /* keyboard controller is present by default */
+RESIDUAL hold_resid_buf;
+RESIDUAL *hold_residual = &hold_resid_buf;
+unsigned long initrd_start = 0, initrd_end = 0;
+char *zimage_start;
+int zimage_size;
+
+char *vidmem = (char *)0xC00B8000;
+int lines, cols;
+int orig_x, orig_y;
+
+extern void puts(const char *);
+extern void putc(const char c);
+extern int tstc(void);
+extern int getc(void);
+extern void puthex(unsigned long val);
+extern void * memcpy(void * __dest, __const void * __src, __kernel_size_t __n);
+extern int CRT_tstc(void);
+extern void of_init(void *handler);
+extern int of_finddevice(const char *device_specifier, int *phandle);
+extern int of_getprop(int phandle, const char *name, void *buf, int buflen,
+ int *size);
+extern __kernel_size_t strlen(const char *s);
+extern int vga_init(unsigned char *ISA_mem);
+extern void udelay(long x);
+void gunzip(void *, int, unsigned char *, int *);
+unsigned char inb(int);
+
+void
+writel(unsigned int val, unsigned int address)
+{
+ /* Ensure I/O operations complete */
+ __asm__ volatile("eieio");
+ *(unsigned int *)address = cpu_to_le32(val);
+}
+
+unsigned int
+readl(unsigned int address)
+{
+ /* Ensure I/O operations complete */
+ __asm__ volatile("eieio");
+ return le32_to_cpu(*(unsigned int *)address);
+}
+
+#define PCI_CFG_ADDR(dev,off) ((0x80<<24) | (dev<<8) | (off&0xfc))
+#define PCI_CFG_DATA(off) (0x80000cfc+(off&3))
+
+static void
+pci_read_config_32(unsigned char devfn,
+ unsigned char offset,
+ unsigned int *val)
+{
+ writel(PCI_CFG_ADDR(devfn,offset), 0x80000cf8);
+ *val = readl(PCI_CFG_DATA(offset));
+ return;
+}
+
+void
+scroll()
+{
+ int i;
+
+ memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 );
+ for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 )
+ vidmem[i] = ' ';
+}
+
+/*
+ * This routine is used to control the second processor on the
+ * Motorola dual processor platforms.
+ */
+void
+park_cpus()
+{
+ volatile void (*go)(RESIDUAL *, int, int, char *, int);
+ unsigned int i;
+ volatile unsigned long *smp_iar = &(hold_residual->VitalProductData.SmpIar);
+
+ /* Wait for indication to continue. If the kernel
+ was not compiled with SMP support then the second
+ processor will spin forever here makeing the kernel
+ multiprocessor safe. */
+ while (*smp_iar == 0) {
+ for (i=0; i < 512; i++);
+ }
+
+ (unsigned long)go = hold_residual->VitalProductData.SmpIar;
+ go(hold_residual, 0, 0, cmd_line, sizeof(cmd_preset));
+}
+
+unsigned long
+decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
+ RESIDUAL *residual, void *OFW_interface)
+{
+ int timer;
+ extern unsigned long start;
+ char *cp, ch;
+ unsigned long TotalMemory;
+ unsigned long orig_MSR;
+ int dev_handle;
+ int mem_info[2];
+ int res, size;
+ unsigned char board_type;
+ unsigned char base_mod;
+ int start_multi = 0;
+ unsigned int pci_viddid, pci_did, tulip_pci_base, tulip_base;
+
+ lines = 25;
+ cols = 80;
+ orig_x = 0;
+ orig_y = 24;
+
+ /*
+ * IBM's have the MMU on, so we have to disable it or
+ * things get really unhappy in the kernel when
+ * trying to setup the BATs with the MMU on
+ * -- Cort
+ */
+ flush_instruction_cache();
+ _put_HID0(_get_HID0() & ~0x0000C000);
+ _put_MSR((orig_MSR = _get_MSR()) & ~0x0030);
+
+#if defined(CONFIG_SERIAL_CONSOLE)
+ com_port = serial_init(0);
+#endif /* CONFIG_SERIAL_CONSOLE */
+ vga_init((char)0xC0000000);
+
+ if (residual)
+ {
+ /* Is this Motorola PPCBug? */
+ if ((1 & residual->VitalProductData.FirmwareSupports) &&
+ (1 == residual->VitalProductData.FirmwareSupplier)) {
+ board_type = inb(0x800) & 0xF0;
+
+ /*
+ * Reset the onboard 21x4x Ethernet
+ * Motorola Ethernet is at IDSEL 14 (devfn 0x70)
+ */
+ pci_read_config_32(0x70, 0x00, &pci_viddid);
+ pci_did = (pci_viddid & 0xffff0000) >> 16;
+ /* Be sure we've really found a 21x4x chip */
+ if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_DEC) &&
+ ((pci_did == PCI_DEVICE_ID_DEC_TULIP_FAST) ||
+ (pci_did == PCI_DEVICE_ID_DEC_TULIP) ||
+ (pci_did == PCI_DEVICE_ID_DEC_TULIP_PLUS) ||
+ (pci_did == PCI_DEVICE_ID_DEC_21142)))
+ {
+ pci_read_config_32(0x70,
+ 0x10,
+ &tulip_pci_base);
+ /* Get the physical base address */
+ tulip_base =
+ (tulip_pci_base & ~0x03UL) + 0x80000000;
+ /* Strobe the 21x4x reset bit in CSR0 */
+ writel(0x1, tulip_base);
+ }
+
+ /* If this is genesis 2 board then check for no
+ * keyboard controller and more than one processor.
+ */
+ if (board_type == 0xe0) {
+ base_mod = inb(0x803);
+ /* if a MVME2300/2400 or a Sitka then no keyboard */
+ if((base_mod == 0xFA) || (base_mod == 0xF9) ||
+ (base_mod == 0xE1)) {
+ keyb_present = 0; /* no keyboard */
+ }
+ }
+ /* If this is a multiprocessor system then
+ * park the other processor so that the
+ * kernel knows where to find them.
+ */
+ if (residual->MaxNumCpus > 1) {
+ start_multi = 1;
+ }
+ }
+ memcpy(hold_residual,residual,sizeof(RESIDUAL));
+ } else {
+ /* Assume 32M in the absence of more info... */
+ TotalMemory = 0x02000000;
+ /*
+ * This is a 'best guess' check. We want to make sure
+ * we don't try this on a PReP box without OF
+ * -- Cort
+ */
+ while (OFW_interface && ((unsigned long)OFW_interface < 0x10000000) )
+ {
+ /* The MMU needs to be on when we call OFW */
+ _put_MSR(orig_MSR);
+ of_init(OFW_interface);
+
+ /* get handle to memory description */
+ res = of_finddevice("/memory@0",
+ &dev_handle);
+ // puthex(res); puts("\n");
+ if (res) break;
+
+ /* get the info */
+ // puts("get info = ");
+ res = of_getprop(dev_handle,
+ "reg",
+ mem_info,
+ sizeof(mem_info),
+ &size);
+ // puthex(res); puts(", info = "); puthex(mem_info[0]);
+ // puts(" "); puthex(mem_info[1]); puts("\n");
+ if (res) break;
+
+ TotalMemory = mem_info[1];
+ break;
+ }
+ hold_residual->TotalMemory = TotalMemory;
+ residual = hold_residual;
+ /* Turn MMU back off */
+ _put_MSR(orig_MSR & ~0x0030);
+ }
+
+ if (start_multi) {
+ hold_residual->VitalProductData.SmpIar = 0;
+ hold_residual->Cpus[1].CpuState = CPU_GOOD_FW;
+ residual->VitalProductData.SmpIar = (unsigned long)park_cpus;
+ residual->Cpus[1].CpuState = CPU_GOOD;
+ hold_residual->VitalProductData.Reserved5 = 0xdeadbeef;
+ }
+
+ /* assume the chunk below 8M is free */
+ end_avail = (char *)0x00800000;
+
+ /* tell the user where we were loaded at and where we
+ * were relocated to for debugging this process
+ */
+ puts("loaded at: "); puthex(load_addr);
+ puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n");
+ if ( (unsigned long)load_addr != (unsigned long)&start )
+ {
+ puts("relocated to: "); puthex((unsigned long)&start);
+ puts(" ");
+ puthex((unsigned long)((unsigned long)&start + (4*num_words)));
+ puts("\n");
+ }
+
+ if ( residual )
+ {
+ puts("board data at: "); puthex((unsigned long)residual);
+ puts(" ");
+ puthex((unsigned long)((unsigned long)residual + sizeof(RESIDUAL)));
+ puts("\n");
+ puts("relocated to: ");
+ puthex((unsigned long)hold_residual);
+ puts(" ");
+ puthex((unsigned long)((unsigned long)hold_residual + sizeof(RESIDUAL)));
+ puts("\n");
+ }
+
+ /* we have to subtract 0x10000 here to correct for objdump including the
+ size of the elf header which we strip -- Cort */
+ zimage_start = (char *)(load_addr - 0x10000 + ZIMAGE_OFFSET);
+ zimage_size = ZIMAGE_SIZE;
+
+ if ( INITRD_OFFSET )
+ initrd_start = load_addr - 0x10000 + INITRD_OFFSET;
+ else
+ initrd_start = 0;
+ initrd_end = INITRD_SIZE + initrd_start;
+
+ /*
+ * Find a place to stick the zimage and initrd and
+ * relocate them if we have to. -- Cort
+ */
+ avail_ram = (char *)PAGE_ALIGN((unsigned long)_end);
+ puts("zimage at: "); puthex((unsigned long)zimage_start);
+ puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); puts("\n");
+ if ( (unsigned long)zimage_start <= 0x00800000 )
+ {
+ memcpy( (void *)avail_ram, (void *)zimage_start, zimage_size );
+ zimage_start = (char *)avail_ram;
+ puts("relocated to: "); puthex((unsigned long)zimage_start);
+ puts(" ");
+ puthex((unsigned long)zimage_size+(unsigned long)zimage_start);
+ puts("\n");
+
+ /* relocate initrd */
+ if ( initrd_start )
+ {
+ puts("initrd at: "); puthex(initrd_start);
+ puts(" "); puthex(initrd_end); puts("\n");
+ avail_ram = (char *)PAGE_ALIGN(
+ (unsigned long)zimage_size+(unsigned long)zimage_start);
+ memcpy ((void *)avail_ram, (void *)initrd_start, INITRD_SIZE );
+ initrd_start = (unsigned long)avail_ram;
+ initrd_end = initrd_start + INITRD_SIZE;
+ puts("relocated to: "); puthex(initrd_start);
+ puts(" "); puthex(initrd_end); puts("\n");
+ }
+ } else if ( initrd_start ) {
+ puts("initrd at: "); puthex(initrd_start);
+ puts(" "); puthex(initrd_end); puts("\n");
+ }
+
+ avail_ram = (char *)0x00400000;
+ end_avail = (char *)0x00800000;
+ puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" ");
+ puthex((unsigned long)end_avail); puts("\n");
+
+ if (keyb_present)
+ CRT_tstc(); /* Forces keyboard to be initialized */
+
+ puts("\nLinux/PPC load: ");
+ timer = 0;
+ cp = cmd_line;
+ memcpy (cmd_line, cmd_preset, sizeof(cmd_preset));
+ while ( *cp ) putc(*cp++);
+ while (timer++ < 5*1000) {
+ if (tstc()) {
+ while ((ch = getc()) != '\n' && ch != '\r') {
+ if (ch == '\b') {
+ if (cp != cmd_line) {
+ cp--;
+ puts("\b \b");
+ }
+ } else {
+ *cp++ = ch;
+ putc(ch);
+ }
+ }
+ break; /* Exit 'timer' loop */
+ }
+ udelay(1000); /* 1 msec */
+ }
+ *cp = 0;
+ puts("\n");
+
+ /* mappings on early boot can only handle 16M */
+ if ( (int)(cmd_line[0]) > (16<<20))
+ puts("cmd_line located > 16M\n");
+ if ( (int)hold_residual > (16<<20))
+ puts("hold_residual located > 16M\n");
+ if ( initrd_start > (16<<20))
+ puts("initrd_start located > 16M\n");
+
+ puts("Uncompressing Linux...");
+
+ gunzip(0, 0x400000, zimage_start, &zimage_size);
+ puts("done.\n");
+
+ {
+ struct bi_record *rec;
+
+ rec = (struct bi_record *)PAGE_ALIGN(zimage_size);
+
+ rec->tag = BI_FIRST;
+ rec->size = sizeof(struct bi_record);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_BOOTLOADER_ID;
+ memcpy( (void *)rec->data, "prepboot", 9);
+ rec->size = sizeof(struct bi_record) + 8 + 1;
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_MACHTYPE;
+ rec->data[0] = _MACH_prep;
+ rec->data[1] = 1;
+ rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_CMD_LINE;
+ memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1);
+ rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1;
+ rec = (struct bi_record *)((ulong)rec + rec->size);
+
+ rec->tag = BI_LAST;
+ rec->size = sizeof(struct bi_record);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+ }
+ puts("Now booting the kernel\n");
+ return (unsigned long)hold_residual;
+}
+
+/*
+ * PCI/ISA I/O support
+ */
+
+volatile unsigned char *ISA_io = (unsigned char *)0x80000000;
+volatile unsigned char *ISA_mem = (unsigned char *)0xC0000000;
+
+void
+outb(int port, char val)
+{
+ /* Ensure I/O operations complete */
+ __asm__ volatile("eieio");
+ ISA_io[port] = val;
+}
+
+unsigned char
+inb(int port)
+{
+ /* Ensure I/O operations complete */
+ __asm__ volatile("eieio");
+ return (ISA_io[port]);
+}
+
+unsigned long
+local_to_PCI(unsigned long addr)
+{
+ return ((addr & 0x7FFFFFFF) | 0x80000000);
+}
--- /dev/null
+/*
+ * BK Id: SCCS/s.of1275.c 1.6 05/18/01 15:16:42 cort
+ */
+/* Open Firmware Client Interface */
+
+
+#include "of1275.h"
+
+
+static int (*of_server)(void *) = (int(*)(void*))-1;
+
+void
+of_init(void *handler)
+{
+ of_server = (int(*)(void*))handler;
+}
+
+
+/* 6.3.2.1 Client interface */
+
+
+int
+of_test(const char *name, int *missing)
+{
+ int result;
+ static of_test_service s;
+ s.service = "test";
+ s.n_args = 1;
+ s.n_returns = 1;
+ s.name = name;
+ result = of_server(&s);
+ *missing = s.missing;
+ return result;
+}
+
+
+/* 6.3.2.2 Device tree */
+
+
+int
+of_peer(int phandle, int *sibling_phandle)
+{
+ int result;
+ static of_peer_service s;
+ s.service = "peer";
+ s.n_args = 1;
+ s.n_returns = 1;
+ s.phandle = phandle;
+ result = of_server(&s);
+ *sibling_phandle = s.sibling_phandle;
+ return result;
+}
+
+int
+of_child(int phandle, int *child_phandle)
+{
+ int result;
+ static of_child_service s;
+ s.service = "child";
+ s.n_args = 1;
+ s.n_returns = 1;
+ s.phandle = phandle;
+ result = of_server(&s);
+ *child_phandle = s.child_phandle;
+ return result;
+}
+
+int
+of_parent(int phandle, int *parent_phandle)
+{
+ int result;
+ static of_parent_service s;
+ s.service = "parent";
+ s.n_args = 1;
+ s.n_returns = 1;
+ s.phandle = phandle;
+ result = of_server(&s);
+ *parent_phandle = s.parent_phandle;
+ return result;
+}
+
+int
+of_instance_to_package(int ihandle, int *phandle)
+{
+ int result;
+ static of_instance_to_package_service s;
+ s.service = "instance-to-package";
+ s.n_args = 1;
+ s.n_returns = 1;
+ s.ihandle = ihandle;
+ result = of_server(&s);
+ *phandle = s.phandle;
+ return result;
+}
+
+int
+of_getproplen(int phandle, const char *name, int *proplen)
+{
+ int result;
+ static of_getproplen_service s;
+ s.service = "getproplen";
+ s.n_args = 2;
+ s.n_returns = 1;
+ s.phandle = phandle;
+ s.name = name;
+ result = of_server(&s);
+ *proplen = s.proplen;
+ return result;
+}
+
+int
+of_getprop(int phandle, const char *name, void *buf, int buflen, int *size)
+{
+ int result;
+ static of_getprop_service s;
+ s.service = "getprop";
+ s.n_args = 4;
+ s.n_returns = 1;
+ s.phandle = phandle;
+ s.name = name;
+ s.buf = buf;
+ s.buflen = buflen;
+ result = of_server(&s);
+ *size = s.size;
+ return result;
+}
+
+int
+of_nextprop(int phandle, const char *previous, void *buf, int *flag)
+{
+ int result;
+ static of_nextprop_service s;
+ s.service = "nextprop";
+ s.n_args = 3;
+ s.n_returns = 1;
+ s.phandle = phandle;
+ s.previous = previous;
+ s.buf = buf;
+ result = of_server(&s);
+ *flag = s.flag;
+ return result;
+}
+
+int
+of_setprop(int phandle, const char *name, void *buf, int len, int *size)
+{
+ int result;
+ static of_setprop_service s;
+ s.service = "setprop";
+ s.n_args = 4;
+ s.n_returns = 1;
+ s.phandle = phandle;
+ s.name = name;
+ s.buf = buf;
+ s.len = len;
+ result = of_server(&s);
+ *size = s.size;
+ return result;
+}
+
+int
+of_canon(const char *device_specifier, void *buf, int buflen, int *length)
+{
+ int result;
+ static of_canon_service s;
+ s.service = "canon";
+ s.n_args = 3;
+ s.n_returns = 1;
+ s.device_specifier = device_specifier;
+ s.buf = buf;
+ s.buflen = buflen;
+ result = of_server(&s);
+ *length = s.length;
+ return result;
+}
+
+int
+of_finddevice(const char *device_specifier, int *phandle)
+{
+ int result;
+ static of_finddevice_service s;
+ s.service = "finddevice";
+ s.n_args = 1;
+ s.n_returns = 1;
+ s.device_specifier = device_specifier;
+ result = of_server(&s);
+ *phandle = s.phandle;
+ return result;
+}
+
+int
+of_instance_to_path(int ihandle, void *buf, int buflen, int *length)
+{
+ int result;
+ static of_instance_to_path_service s;
+ s.service = "instance-to-path";
+ s.n_args = 3;
+ s.n_returns = 1;
+ s.ihandle = ihandle;
+ s.buf = buf;
+ s.buflen = buflen;
+ result = of_server(&s);
+ *length = s.length;
+ return result;
+}
+
+int
+of_package_to_path(int phandle, void *buf, int buflen, int *length)
+{
+ int result;
+ static of_package_to_path_service s;
+ s.service = "package-to-path";
+ s.n_args = 3;
+ s.n_returns = 1;
+ s.phandle = phandle;
+ s.buf = buf;
+ s.buflen = buflen;
+ result = of_server(&s);
+ *length = s.length;
+ return result;
+}
+
+/* int of_call_method(const char *method, int ihandle, ...); */
+
+
+/* 6.3.2.3 Device I/O */
+
+
+int
+of_open(const char *device_specifier, int *ihandle)
+{
+ int result;
+ static of_open_service s;
+ s.service = "open";
+ s.n_args = 1;
+ s.n_returns = 1;
+ s.device_specifier = device_specifier;
+ result = of_server(&s);
+ *ihandle = s.ihandle;
+ return result;
+}
+
+int
+of_close(int ihandle)
+{
+ int result;
+ static of_close_service s;
+ s.service = "close";
+ s.n_args = 1;
+ s.n_returns = 0;
+ s.ihandle = ihandle;
+ result = of_server(&s);
+ return result;
+}
+
+int
+of_read(int ihandle, void *addr, int len, int *actual)
+{
+ int result;
+ static of_read_service s;
+ s.service = "read";
+ s.n_args = 3;
+ s.n_returns = 1;
+ s.ihandle = ihandle;
+ s.addr = addr;
+ s.len = len;
+ result = of_server(&s);
+ *actual = s.actual;
+ return result;
+}
+
+int
+of_write(int ihandle, void *addr, int len, int *actual)
+{
+ int result;
+ static of_write_service s;
+ s.service = "write";
+ s.n_args = 3;
+ s.n_returns = 1;
+ s.ihandle = ihandle;
+ s.addr = addr;
+ s.len = len;
+ result = of_server(&s);
+ *actual = s.actual;
+ return result;
+}
+
+int
+of_seek(int ihandle, int pos_hi, int pos_lo, int *status)
+{
+ int result;
+ static of_seek_service s;
+ s.service = "seek";
+ s.n_args = 3;
+ s.n_returns = 1;
+ s.ihandle = ihandle;
+ s.pos_hi = pos_hi;
+ s.pos_lo = pos_lo;
+ result = of_server(&s);
+ *status = s.status;
+ return result;
+}
+
+
+/* 6.3.2.4 Memory */
+
+
+int
+of_claim(void *virt, int size, int align, void **baseaddr)
+{
+ int result;
+ static of_claim_service s;
+ s.service = "claim";
+ s.n_args = 3;
+ s.n_returns = 1;
+ s.virt = virt;
+ s.size = size;
+ s.align = align;
+ result = of_server(&s);
+ *baseaddr = s.baseaddr;
+ return result;
+}
+
+int
+of_release(void *virt, int size)
+{
+ int result;
+ static of_release_service s;
+ s.service = "release";
+ s.n_args = 2;
+ s.n_returns = 0;
+ s.virt = virt;
+ s.size = size;
+ result = of_server(&s);
+ return result;
+}
+
+
+/* 6.3.2.5 Control transfer */
+
+
+int
+of_boot(const char *bootspec)
+{
+ int result;
+ static of_boot_service s;
+ s.service = "boot";
+ s.n_args = 1;
+ s.n_returns = 0;
+ s.bootspec = bootspec;
+ result = of_server(&s);
+ return result;
+}
+
+int
+of_enter(void)
+{
+ int result;
+ static of_enter_service s;
+ s.service = "enter";
+ s.n_args = 0;
+ s.n_returns = 0;
+ result = of_server(&s);
+ return result;
+}
+
+int
+of_exit(void)
+{
+ int result;
+ static of_exit_service s;
+ s.service = "exit";
+ s.n_args = 0;
+ s.n_returns = 0;
+ result = of_server(&s);
+ return result;
+}
+
+/* int of_chain(void *virt, int size, void *entry, void *args, int len); */
+
+
+/* 6.3.2.6 User interface */
+
+
+/* int of_interpret(const char *arg, ...); */
+
+int
+of_set_callback(void *newfunc, void **oldfunc)
+{
+ int result;
+ static of_set_callback_service s;
+ s.service = "set-callback";
+ s.n_args = 1;
+ s.n_returns = 1;
+ s.newfunc = newfunc;
+ result = of_server(&s);
+ *oldfunc = s.oldfunc;
+ return result;
+}
+
+int
+of_set_symbol_lookup(void *sym_to_value, void *value_to_sym)
+{
+ int result;
+ static of_set_symbol_lookup_service s;
+ s.service = "set-symbol-lookup";
+ s.n_args = 2;
+ s.n_returns = 0;
+ s.sym_to_value = sym_to_value;
+ s.value_to_sym = s.value_to_sym;
+ result = of_server(&s);
+ return result;
+}
+
+
+/* 6.3.2.7 Time */
+
+
+int
+of_milliseconds(int *ms)
+{
+ int result;
+ static of_milliseconds_service s;
+ s.service = "milliseconds";
+ s.n_args = 0;
+ s.n_returns = 1;
+ result = of_server(&s);
+ *ms = s.ms;
+ return result;
+}
--- /dev/null
+/*
+ * BK Id: SCCS/s.of1275.h 1.6 05/18/01 15:16:42 cort
+ */
+/* 6.3.2.1 Client interface */
+
+
+typedef struct _of_test_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ const char *name;
+ /*out*/
+ int missing;
+} of_test_service;
+
+int of_test(const char *name, int *missing);
+
+
+/* 6.3.2.2 Device tree */
+
+
+typedef struct _of_peer_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ int phandle;
+ /*out*/
+ int sibling_phandle;
+} of_peer_service;
+
+int of_peer(int phandle, int *sibling_phandle);
+
+
+typedef struct _of_child_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ int phandle;
+ /*out*/
+ int child_phandle;
+} of_child_service;
+
+int of_child(int phandle, int *child_phandle);
+
+
+typedef struct _of_parent_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ int phandle;
+ /*out*/
+ int parent_phandle;
+} of_parent_service;
+
+int of_child(int phandle, int *parent_phandle);
+
+
+typedef struct _of_instance_to_package_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ int ihandle;
+ /*out*/
+ int phandle;
+} of_instance_to_package_service;
+
+int of_instance_to_package(int ihandle, int *phandle);
+
+
+typedef struct _of_getproplen_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ int phandle;
+ const char *name;
+ /*out*/
+ int proplen;
+} of_getproplen_service;
+
+int of_getproplen(int phandle, const char *name, int *proplen);
+
+
+typedef struct _of_getprop_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ int phandle;
+ const char *name;
+ void *buf;
+ int buflen;
+ /*out*/
+ int size;
+} of_getprop_service;
+
+int of_getprop(int phandle, const char *name, void *buf, int buflen,
+ int *size);
+
+
+typedef struct _of_nextprop_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ int phandle;
+ const char *previous;
+ void *buf;
+ /*out*/
+ int flag;
+} of_nextprop_service;
+
+int of_nextprop(int phandle, const char *previous, void *buf, int *flag);
+
+
+typedef struct _of_setprop_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ int phandle;
+ const char *name;
+ void *buf;
+ int len;
+ /*out*/
+ int size;
+} of_setprop_service;
+
+int of_setprop(int phandle, const char *name, void *buf, int len, int *size);
+
+
+typedef struct _of_canon_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ const char *device_specifier;
+ void *buf;
+ int buflen;
+ /*out*/
+ int length;
+} of_canon_service;
+
+int of_canon(const char *device_specifier, void *buf, int buflen, int *length);
+
+
+typedef struct _of_finddevice_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ const char *device_specifier;
+ /*out*/
+ int phandle;
+} of_finddevice_service;
+
+int of_finddevice(const char *device_specifier, int *phandle);
+
+
+typedef struct _of_instance_to_path_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ int ihandle;
+ void *buf;
+ int buflen;
+ /*out*/
+ int length;
+} of_instance_to_path_service;
+
+int of_instance_to_path(int ihandle, void *buf, int buflen, int *length);
+
+
+typedef struct _of_package_to_path_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ int phandle;
+ void *buf;
+ int buflen;
+ /*out*/
+ int length;
+} of_package_to_path_service;
+
+int of_package_to_path(int phandle, void *buf, int buflen, int *length);
+
+
+typedef struct _of_call_method_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ const char *method;
+ int ihandle;
+ /*...*/
+ int args[0];
+} of_call_method_service;
+
+int of_call_method(const char *method, int ihandle, ...);
+
+
+/* 6.3.2.3 Device I/O */
+
+
+typedef struct _of_open_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ const char *device_specifier;
+ /*out*/
+ int ihandle;
+} of_open_service;
+
+int of_open(const char *device_specifier,
+ int *ihandle);
+
+
+typedef struct _of_close_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ int ihandle;
+ /*out*/
+} of_close_service;
+
+int of_close(int ihandle);
+
+
+typedef struct _of_read_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ int ihandle;
+ void *addr;
+ int len;
+ /*out*/
+ int actual;
+} of_read_service;
+
+int of_read(int ihandle, void *addr, int len, int *actual);
+
+
+typedef struct _of_write_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ int ihandle;
+ void *addr;
+ int len;
+ /*out*/
+ int actual;
+} of_write_service;
+
+int of_write(int ihandle, void *addr, int len, int *actual);
+
+
+typedef struct _of_seek_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ int ihandle;
+ int pos_hi;
+ int pos_lo;
+ /*out*/
+ int status;
+} of_seek_service;
+
+int of_seek(int ihandle, int pos_hi, int pos_lo, int *status);
+
+
+/* 6.3.2.4 Memory */
+
+
+typedef struct _of_claim_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ void *virt;
+ int size;
+ int align;
+ /*out*/
+ void *baseaddr;
+} of_claim_service;
+
+int of_claim(void *virt, int size, int align, void **baseaddr);
+
+
+typedef struct _of_release_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ void *virt;
+ int size;
+ int align;
+ /*out*/
+} of_release_service;
+
+int of_release(void *virt, int size);
+
+
+/* 6.3.2.5 Control transfer */
+
+
+typedef struct _of_boot_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ const char *bootspec;
+ /*out*/
+} of_boot_service;
+
+int of_boot(const char *bootspec);
+
+
+typedef struct _of_enter_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ /*out*/
+} of_enter_service;
+
+int of_enter(void);
+
+
+typedef struct _of_exit_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ /*out*/
+} of_exit_service;
+
+int of_exit(void);
+
+
+typedef struct _of_chain_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ void *virt;
+ int size;
+ void *entry;
+ void *args;
+ int len;
+ /*out*/
+} of_chain_service;
+
+int of_chain(void *virt, int size, void *entry, void *args, int len);
+
+
+/* 6.3.2.6 User interface */
+
+
+typedef struct _of_interpret_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ const char *cmd;
+ int args[0];
+ /*...*/
+ /*out*/
+ /*...*/
+} of_interpret_service;
+
+int of_interpret(const char *arg, ...);
+
+
+typedef struct _of_set_callback_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ void *newfunc;
+ /*out*/
+ void *oldfunc;
+} of_set_callback_service;
+
+int of_set_callback(void *newfunc, void **oldfunc);
+
+
+typedef struct _of_set_symbol_lookup_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ void *sym_to_value;
+ void *value_to_sym;
+ /*out*/
+} of_set_symbol_lookup_service;
+
+int of_set_symbol_lookup(void *sym_to_value, void *value_to_sym);
+
+
+/* 6.3.2.7 Time */
+
+
+typedef struct _of_milliseconds_service {
+ const char *service;
+ int n_args;
+ int n_returns;
+ /*in*/
+ /*out*/
+ int ms;
+} of_milliseconds_service;
+
+int of_milliseconds(int *ms);
--- /dev/null
+/*
+ * BK Id: SCCS/s.vreset.c 1.9 05/18/01 06:20:29 patch
+ */
+/*
+ * vreset.c
+ *
+ * Initialize the VGA control registers to 80x25 text mode.
+ *
+ * Adapted from a program by:
+ * Steve Sellgren
+ * San Francisco Indigo Company
+ * sfindigo!sellgren@uunet.uu.net
+ *
+ * Original concept by:
+ * Gary Thomas <gdt@linuxppc.org>
+ * Adapted for Moto boxes by:
+ * Pat Kane & Mark Scott, 1996
+ * Adapted for IBM portables by:
+ * Takeshi Ishimoto
+ * Multi-console support:
+ * Terje Malmedal <terje.malmedal@usit.uio.no>
+ */
+
+#include "iso_font.h"
+
+extern char *vidmem;
+extern int lines, cols;
+extern void udelay(long x);
+extern void outb(int port, char val);
+extern unsigned char inb(int port);
+struct VaRegs;
+
+/*
+ * VGA Register
+ */
+struct VgaRegs
+{
+ unsigned short io_port;
+ unsigned char io_index;
+ unsigned char io_value;
+};
+
+void unlockVideo(int slot);
+void setTextRegs(struct VgaRegs *svp);
+void setTextCLUT(int shift);
+void clearVideoMemory();
+void loadFont(unsigned char *ISA_mem);
+
+static void mdelay(int ms)
+{
+ for (; ms > 0; --ms)
+ udelay(1000);
+}
+
+/*
+ * Default console text mode registers used to reset
+ * graphics adapter.
+ */
+#define NREGS 54
+#define ENDMK 0xFFFF /* End marker */
+
+#define S3Vendor 0x5333
+#define CirrusVendor 0x1013
+#define DiamondVendor 0x100E
+#define MatroxVendor 0x102B
+#define ParadiseVendor 0x101C
+
+struct VgaRegs GenVgaTextRegs[NREGS+1] = {
+/* port index value */
+ /* SR Regs */
+ 0x3c4, 0x1, 0x0,
+ 0x3c4, 0x2, 0x3,
+ 0x3c4, 0x3, 0x0,
+ 0x3c4, 0x4, 0x2,
+ /* CR Regs */
+ 0x3d4, 0x0, 0x5f,
+ 0x3d4, 0x1, 0x4f,
+ 0x3d4, 0x2, 0x50,
+ 0x3d4, 0x3, 0x82,
+ 0x3d4, 0x4, 0x55,
+ 0x3d4, 0x5, 0x81,
+ 0x3d4, 0x6, 0xbf,
+ 0x3d4, 0x7, 0x1f,
+ 0x3d4, 0x8, 0x00,
+ 0x3d4, 0x9, 0x4f,
+ 0x3d4, 0xa, 0x0d,
+ 0x3d4, 0xb, 0x0e,
+ 0x3d4, 0xc, 0x00,
+ 0x3d4, 0xd, 0x00,
+ 0x3d4, 0xe, 0x00,
+ 0x3d4, 0xf, 0x00,
+ 0x3d4, 0x10, 0x9c,
+ 0x3d4, 0x11, 0x8e,
+ 0x3d4, 0x12, 0x8f,
+ 0x3d4, 0x13, 0x28,
+ 0x3d4, 0x14, 0x1f,
+ 0x3d4, 0x15, 0x96,
+ 0x3d4, 0x16, 0xb9,
+ 0x3d4, 0x17, 0xa3,
+ /* GR Regs */
+ 0x3ce, 0x0, 0x0,
+ 0x3ce, 0x1, 0x0,
+ 0x3ce, 0x2, 0x0,
+ 0x3ce, 0x3, 0x0,
+ 0x3ce, 0x4, 0x0,
+ 0x3ce, 0x5, 0x10,
+ 0x3ce, 0x6, 0xe,
+ 0x3ce, 0x7, 0x0,
+ 0x3ce, 0x8, 0xff,
+ ENDMK
+};
+
+struct VgaRegs S3TextRegs[NREGS+1] = {
+/* port index value */
+ /* SR Regs */
+ 0x3c4, 0x1, 0x0,
+ 0x3c4, 0x2, 0x3,
+ 0x3c4, 0x3, 0x0,
+ 0x3c4, 0x4, 0x2,
+ /* CR Regs */
+ 0x3d4, 0x0, 0x5f,
+ 0x3d4, 0x1, 0x4f,
+ 0x3d4, 0x2, 0x50,
+ 0x3d4, 0x3, 0x82,
+ 0x3d4, 0x4, 0x55,
+ 0x3d4, 0x5, 0x81,
+ 0x3d4, 0x6, 0xbf,
+ 0x3d4, 0x7, 0x1f,
+ 0x3d4, 0x8, 0x00,
+ 0x3d4, 0x9, 0x4f,
+ 0x3d4, 0xa, 0x0d,
+ 0x3d4, 0xb, 0x0e,
+ 0x3d4, 0xc, 0x00,
+ 0x3d4, 0xd, 0x00,
+ 0x3d4, 0xe, 0x00,
+ 0x3d4, 0xf, 0x00,
+ 0x3d4, 0x10, 0x9c,
+ 0x3d4, 0x11, 0x8e,
+ 0x3d4, 0x12, 0x8f,
+ 0x3d4, 0x13, 0x28,
+ 0x3d4, 0x14, 0x1f,
+ 0x3d4, 0x15, 0x96,
+ 0x3d4, 0x16, 0xb9,
+ 0x3d4, 0x17, 0xa3,
+ /* GR Regs */
+ 0x3ce, 0x0, 0x0,
+ 0x3ce, 0x1, 0x0,
+ 0x3ce, 0x2, 0x0,
+ 0x3ce, 0x3, 0x0,
+ 0x3ce, 0x4, 0x0,
+ 0x3ce, 0x5, 0x10,
+ 0x3ce, 0x6, 0xe,
+ 0x3ce, 0x7, 0x0,
+ 0x3ce, 0x8, 0xff,
+ ENDMK
+};
+
+struct RGBColors
+{
+ unsigned char r, g, b;
+};
+
+/*
+ * Default console text mode color table.
+ * These values were obtained by booting Linux with
+ * text mode firmware & then dumping the registers.
+ */
+struct RGBColors TextCLUT[256] =
+{
+ /* red green blue */
+ 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x2a,
+ 0x0, 0x2a, 0x0,
+ 0x0, 0x2a, 0x2a,
+ 0x2a, 0x0, 0x0,
+ 0x2a, 0x0, 0x2a,
+ 0x2a, 0x2a, 0x0,
+ 0x2a, 0x2a, 0x2a,
+ 0x0, 0x0, 0x15,
+ 0x0, 0x0, 0x3f,
+ 0x0, 0x2a, 0x15,
+ 0x0, 0x2a, 0x3f,
+ 0x2a, 0x0, 0x15,
+ 0x2a, 0x0, 0x3f,
+ 0x2a, 0x2a, 0x15,
+ 0x2a, 0x2a, 0x3f,
+ 0x0, 0x15, 0x0,
+ 0x0, 0x15, 0x2a,
+ 0x0, 0x3f, 0x0,
+ 0x0, 0x3f, 0x2a,
+ 0x2a, 0x15, 0x0,
+ 0x2a, 0x15, 0x2a,
+ 0x2a, 0x3f, 0x0,
+ 0x2a, 0x3f, 0x2a,
+ 0x0, 0x15, 0x15,
+ 0x0, 0x15, 0x3f,
+ 0x0, 0x3f, 0x15,
+ 0x0, 0x3f, 0x3f,
+ 0x2a, 0x15, 0x15,
+ 0x2a, 0x15, 0x3f,
+ 0x2a, 0x3f, 0x15,
+ 0x2a, 0x3f, 0x3f,
+ 0x15, 0x0, 0x0,
+ 0x15, 0x0, 0x2a,
+ 0x15, 0x2a, 0x0,
+ 0x15, 0x2a, 0x2a,
+ 0x3f, 0x0, 0x0,
+ 0x3f, 0x0, 0x2a,
+ 0x3f, 0x2a, 0x0,
+ 0x3f, 0x2a, 0x2a,
+ 0x15, 0x0, 0x15,
+ 0x15, 0x0, 0x3f,
+ 0x15, 0x2a, 0x15,
+ 0x15, 0x2a, 0x3f,
+ 0x3f, 0x0, 0x15,
+ 0x3f, 0x0, 0x3f,
+ 0x3f, 0x2a, 0x15,
+ 0x3f, 0x2a, 0x3f,
+ 0x15, 0x15, 0x0,
+ 0x15, 0x15, 0x2a,
+ 0x15, 0x3f, 0x0,
+ 0x15, 0x3f, 0x2a,
+ 0x3f, 0x15, 0x0,
+ 0x3f, 0x15, 0x2a,
+ 0x3f, 0x3f, 0x0,
+ 0x3f, 0x3f, 0x2a,
+ 0x15, 0x15, 0x15,
+ 0x15, 0x15, 0x3f,
+ 0x15, 0x3f, 0x15,
+ 0x15, 0x3f, 0x3f,
+ 0x3f, 0x15, 0x15,
+ 0x3f, 0x15, 0x3f,
+ 0x3f, 0x3f, 0x15,
+ 0x3f, 0x3f, 0x3f,
+ 0x39, 0xc, 0x5,
+ 0x15, 0x2c, 0xf,
+ 0x26, 0x10, 0x3d,
+ 0x29, 0x29, 0x38,
+ 0x4, 0x1a, 0xe,
+ 0x2, 0x1e, 0x3a,
+ 0x3c, 0x25, 0x33,
+ 0x3c, 0xc, 0x2c,
+ 0x3f, 0x3, 0x2b,
+ 0x1c, 0x9, 0x13,
+ 0x25, 0x2a, 0x35,
+ 0x1e, 0xa, 0x38,
+ 0x24, 0x8, 0x3,
+ 0x3, 0xe, 0x36,
+ 0xc, 0x6, 0x2a,
+ 0x26, 0x3, 0x32,
+ 0x5, 0x2f, 0x33,
+ 0x3c, 0x35, 0x2f,
+ 0x2d, 0x26, 0x3e,
+ 0xd, 0xa, 0x10,
+ 0x25, 0x3c, 0x11,
+ 0xd, 0x4, 0x2e,
+ 0x5, 0x19, 0x3e,
+ 0xc, 0x13, 0x34,
+ 0x2b, 0x6, 0x24,
+ 0x4, 0x3, 0xd,
+ 0x2f, 0x3c, 0xc,
+ 0x2a, 0x37, 0x1f,
+ 0xf, 0x12, 0x38,
+ 0x38, 0xe, 0x2a,
+ 0x12, 0x2f, 0x19,
+ 0x29, 0x2e, 0x31,
+ 0x25, 0x13, 0x3e,
+ 0x33, 0x3e, 0x33,
+ 0x1d, 0x2c, 0x25,
+ 0x15, 0x15, 0x5,
+ 0x32, 0x25, 0x39,
+ 0x1a, 0x7, 0x1f,
+ 0x13, 0xe, 0x1d,
+ 0x36, 0x17, 0x34,
+ 0xf, 0x15, 0x23,
+ 0x2, 0x35, 0xd,
+ 0x15, 0x3f, 0xc,
+ 0x14, 0x2f, 0xf,
+ 0x19, 0x21, 0x3e,
+ 0x27, 0x11, 0x2f,
+ 0x38, 0x3f, 0x3c,
+ 0x36, 0x2d, 0x15,
+ 0x16, 0x17, 0x2,
+ 0x1, 0xa, 0x3d,
+ 0x1b, 0x11, 0x3f,
+ 0x21, 0x3c, 0xd,
+ 0x1a, 0x39, 0x3d,
+ 0x8, 0xe, 0xe,
+ 0x22, 0x21, 0x23,
+ 0x1e, 0x30, 0x5,
+ 0x1f, 0x22, 0x3d,
+ 0x1e, 0x2f, 0xa,
+ 0x0, 0x1c, 0xe,
+ 0x0, 0x1c, 0x15,
+ 0x0, 0x1c, 0x1c,
+ 0x0, 0x15, 0x1c,
+ 0x0, 0xe, 0x1c,
+ 0x0, 0x7, 0x1c,
+ 0xe, 0xe, 0x1c,
+ 0x11, 0xe, 0x1c,
+ 0x15, 0xe, 0x1c,
+ 0x18, 0xe, 0x1c,
+ 0x1c, 0xe, 0x1c,
+ 0x1c, 0xe, 0x18,
+ 0x1c, 0xe, 0x15,
+ 0x1c, 0xe, 0x11,
+ 0x1c, 0xe, 0xe,
+ 0x1c, 0x11, 0xe,
+ 0x1c, 0x15, 0xe,
+ 0x1c, 0x18, 0xe,
+ 0x1c, 0x1c, 0xe,
+ 0x18, 0x1c, 0xe,
+ 0x15, 0x1c, 0xe,
+ 0x11, 0x1c, 0xe,
+ 0xe, 0x1c, 0xe,
+ 0xe, 0x1c, 0x11,
+ 0xe, 0x1c, 0x15,
+ 0xe, 0x1c, 0x18,
+ 0xe, 0x1c, 0x1c,
+ 0xe, 0x18, 0x1c,
+ 0xe, 0x15, 0x1c,
+ 0xe, 0x11, 0x1c,
+ 0x14, 0x14, 0x1c,
+ 0x16, 0x14, 0x1c,
+ 0x18, 0x14, 0x1c,
+ 0x1a, 0x14, 0x1c,
+ 0x1c, 0x14, 0x1c,
+ 0x1c, 0x14, 0x1a,
+ 0x1c, 0x14, 0x18,
+ 0x1c, 0x14, 0x16,
+ 0x1c, 0x14, 0x14,
+ 0x1c, 0x16, 0x14,
+ 0x1c, 0x18, 0x14,
+ 0x1c, 0x1a, 0x14,
+ 0x1c, 0x1c, 0x14,
+ 0x1a, 0x1c, 0x14,
+ 0x18, 0x1c, 0x14,
+ 0x16, 0x1c, 0x14,
+ 0x14, 0x1c, 0x14,
+ 0x14, 0x1c, 0x16,
+ 0x14, 0x1c, 0x18,
+ 0x14, 0x1c, 0x1a,
+ 0x14, 0x1c, 0x1c,
+ 0x14, 0x1a, 0x1c,
+ 0x14, 0x18, 0x1c,
+ 0x14, 0x16, 0x1c,
+ 0x0, 0x0, 0x10,
+ 0x4, 0x0, 0x10,
+ 0x8, 0x0, 0x10,
+ 0xc, 0x0, 0x10,
+ 0x10, 0x0, 0x10,
+ 0x10, 0x0, 0xc,
+ 0x10, 0x0, 0x8,
+ 0x10, 0x0, 0x4,
+ 0x10, 0x0, 0x0,
+ 0x10, 0x4, 0x0,
+ 0x10, 0x8, 0x0,
+ 0x10, 0xc, 0x0,
+ 0x10, 0x10, 0x0,
+ 0xc, 0x10, 0x0,
+ 0x8, 0x10, 0x0,
+ 0x4, 0x10, 0x0,
+ 0x0, 0x10, 0x0,
+ 0x0, 0x10, 0x4,
+ 0x0, 0x10, 0x8,
+ 0x0, 0x10, 0xc,
+ 0x0, 0x10, 0x10,
+ 0x0, 0xc, 0x10,
+ 0x0, 0x8, 0x10,
+ 0x0, 0x4, 0x10,
+ 0x8, 0x8, 0x10,
+ 0xa, 0x8, 0x10,
+ 0xc, 0x8, 0x10,
+ 0xe, 0x8, 0x10,
+ 0x10, 0x8, 0x10,
+ 0x10, 0x8, 0xe,
+ 0x10, 0x8, 0xc,
+ 0x10, 0x8, 0xa,
+ 0x10, 0x8, 0x8,
+ 0x10, 0xa, 0x8,
+ 0x10, 0xc, 0x8,
+ 0x10, 0xe, 0x8,
+ 0x10, 0x10, 0x8,
+ 0xe, 0x10, 0x8,
+ 0xc, 0x10, 0x8,
+ 0xa, 0x10, 0x8,
+ 0x8, 0x10, 0x8,
+ 0x8, 0x10, 0xa,
+ 0x8, 0x10, 0xc,
+ 0x8, 0x10, 0xe,
+ 0x8, 0x10, 0x10,
+ 0x8, 0xe, 0x10,
+ 0x8, 0xc, 0x10,
+ 0x8, 0xa, 0x10,
+ 0xb, 0xb, 0x10,
+ 0xc, 0xb, 0x10,
+ 0xd, 0xb, 0x10,
+ 0xf, 0xb, 0x10,
+ 0x10, 0xb, 0x10,
+ 0x10, 0xb, 0xf,
+ 0x10, 0xb, 0xd,
+ 0x10, 0xb, 0xc,
+ 0x10, 0xb, 0xb,
+ 0x10, 0xc, 0xb,
+ 0x10, 0xd, 0xb,
+ 0x10, 0xf, 0xb,
+ 0x10, 0x10, 0xb,
+ 0xf, 0x10, 0xb,
+ 0xd, 0x10, 0xb,
+ 0xc, 0x10, 0xb,
+ 0xb, 0x10, 0xb,
+ 0xb, 0x10, 0xc,
+ 0xb, 0x10, 0xd,
+ 0xb, 0x10, 0xf,
+ 0xb, 0x10, 0x10,
+ 0xb, 0xf, 0x10,
+ 0xb, 0xd, 0x10,
+ 0xb, 0xc, 0x10,
+ 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0
+};
+
+unsigned char AC[21] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+ 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+ 0x0C, 0x00, 0x0F, 0x08, 0x00};
+
+static int scanPCI(int start_slt);
+static int PCIVendor(int);
+#ifdef DEBUG
+static void printslots(void);
+#endif
+extern void puthex(unsigned long);
+extern void puts(const char *);
+static void unlockS3(void);
+
+static void inline
+outw(int port, unsigned short val)
+{
+ outb(port, val >> 8);
+ outb(port+1, val);
+}
+
+#define PPC_601 1
+
+int
+vga_init(unsigned char *ISA_mem)
+{
+ int slot;
+ struct VgaRegs *VgaTextRegs;
+#if 0
+ if ((_get_PVR()>>16) == PPC_601) {
+ return(old_vga_init(ISA_mem));
+ }
+#endif
+
+ /* See if VGA already in TEXT mode - exit if so! */
+ outb(0x3CE, 0x06);
+ if ((inb(0x3CF) & 0x01) == 0){
+ puts("VGA already in text mode\n");
+ return 0;
+ }
+
+ /* If no VGA responding in text mode, then we have some work to do...
+ */
+ slot = -1;
+ while((slot = scanPCI(slot)) > -1) { /* find video card in use */
+ unlockVideo(slot); /* enable I/O to card */
+ VgaTextRegs = GenVgaTextRegs;
+
+ switch (PCIVendor(slot)) {
+ default:
+ break;
+ case(S3Vendor):
+ unlockS3();
+ VgaTextRegs = S3TextRegs;
+ break;
+
+ case(CirrusVendor):
+ outw(0x3C4, 0x0612); /* unlock ext regs */
+ outw(0x3C4, 0x0700); /* reset ext sequence mode */
+ break;
+
+ case(ParadiseVendor): /* IBM Portable 850 */
+ outw(0x3ce, 0x0f05); /* unlock pardise registers */
+ outw(0x3c4, 0x0648);
+ outw(0x3d4, 0x2985);
+ outw(0x3d4, 0x34a6);
+ outb(0x3ce, 0x0b); /* disable linear addressing */
+ outb(0x3cf, inb(0x3cf) & ~0x30);
+ outw(0x3c4, 0x1400);
+ outb(0x3ce, 0x0e); /* disable 256 color mode */
+ outb(0x3cf, inb(0x3cf) & ~0x01);
+ outb(0xd00, 0xff); /* enable auto-centering */
+ if (!(inb(0xd01) & 0x03)) {
+ outb(0x3d4, 0x33);
+ outb(0x3d5, inb(0x3d5) & ~0x90);
+ outb(0x3d4, 0x32);
+ outb(0x3d5, inb(0x3d5) | 0x04);
+ outw(0x3d4, 0x0250);
+ outw(0x3d4, 0x07ba);
+ outw(0x3d4, 0x0900);
+ outw(0x3d4, 0x15e7);
+ outw(0x3d4, 0x2a95);
+ }
+ outw(0x3d4, 0x34a0);
+ break;
+
+ #if 0 /* Untested - probably doesn't work */
+ case(MatroxVendor):
+ case(DiamondVendor):
+ puts("VGA Chip Vendor ID: ");
+ puthex(PCIVendor(slot));
+ puts("\n");
+ mdelay(1000);
+ #endif
+ };
+
+ outw(0x3C4, 0x0120); /* disable video */
+ setTextRegs(VgaTextRegs); /* initial register setup */
+ setTextCLUT(0); /* load color lookup table */
+ loadFont(ISA_mem); /* load font */
+ setTextRegs(VgaTextRegs); /* reload registers */
+ outw(0x3C4, 0x0100); /* re-enable video */
+ clearVideoMemory();
+
+ if (PCIVendor(slot) == S3Vendor) {
+ outb(0x3c2, 0x63); /* MISC */
+ } /* endif */
+
+ #ifdef DEBUG
+ printslots();
+ mdelay(5000);
+ #endif
+
+ mdelay(1000); /* give time for the video monitor to come up */
+ }
+ return (1); /* 'CRT' I/O supported */
+}
+
+/*
+ * Write to VGA Attribute registers.
+ */
+void
+writeAttr(unsigned char index, unsigned char data, unsigned char videoOn)
+{
+ unsigned char v;
+ v = inb(0x3da); /* reset attr. address toggle */
+ if (videoOn)
+ outb(0x3c0, (index & 0x1F) | 0x20);
+ else
+ outb(0x3c0, (index & 0x1F));
+ outb(0x3c0, data);
+}
+
+void
+setTextRegs(struct VgaRegs *svp)
+{
+ int i;
+
+ /*
+ * saved settings
+ */
+ while( svp->io_port != ENDMK ) {
+ outb(svp->io_port, svp->io_index);
+ outb(svp->io_port+1, svp->io_value);
+ svp++;
+ }
+
+ outb(0x3c2, 0x67); /* MISC */
+ outb(0x3c6, 0xff); /* MASK */
+
+ for ( i = 0; i < 0x10; i++)
+ writeAttr(i, AC[i], 0); /* pallete */
+ writeAttr(0x10, 0x0c, 0); /* text mode */
+ writeAttr(0x11, 0x00, 0); /* overscan color (border) */
+ writeAttr(0x12, 0x0f, 0); /* plane enable */
+ writeAttr(0x13, 0x08, 0); /* pixel panning */
+ writeAttr(0x14, 0x00, 1); /* color select; video on */
+}
+
+void
+setTextCLUT(int shift)
+{
+ int i;
+
+ outb(0x3C6, 0xFF);
+ i = inb(0x3C7);
+ outb(0x3C8, 0);
+ i = inb(0x3C7);
+
+ for ( i = 0; i < 256; i++) {
+ outb(0x3C9, TextCLUT[i].r << shift);
+ outb(0x3C9, TextCLUT[i].g << shift);
+ outb(0x3C9, TextCLUT[i].b << shift);
+ }
+}
+
+void
+loadFont(unsigned char *ISA_mem)
+{
+ int i, j;
+ unsigned char *font_page = (unsigned char *) &ISA_mem[0xA0000];
+
+ outb(0x3C2, 0x67);
+ /*
+ * Load font
+ */
+ i = inb(0x3DA); /* Reset Attr toggle */
+
+ outb(0x3C0,0x30);
+ outb(0x3C0, 0x01); /* graphics mode */
+
+ outw(0x3C4, 0x0001); /* reset sequencer */
+ outw(0x3C4, 0x0204); /* write to plane 2 */
+ outw(0x3C4, 0x0406); /* enable plane graphics */
+ outw(0x3C4, 0x0003); /* reset sequencer */
+ outw(0x3CE, 0x0402); /* read plane 2 */
+ outw(0x3CE, 0x0500); /* write mode 0, read mode 0 */
+ outw(0x3CE, 0x0605); /* set graphics mode */
+
+ for (i = 0; i < sizeof(font); i += 16) {
+ for (j = 0; j < 16; j++) {
+ __asm__ volatile("eieio");
+ font_page[(2*i)+j] = font[i+j];
+ }
+ }
+}
+
+static void
+unlockS3(void)
+{
+ int s3_device_id;
+ outw(0x3d4, 0x3848);
+ outw(0x3d4, 0x39a5);
+ outb(0x3d4, 0x2d);
+ s3_device_id = inb(0x3d5) << 8;
+ outb(0x3d4, 0x2e);
+ s3_device_id |= inb(0x3d5);
+
+ if (s3_device_id != 0x8812) {
+ /* From the S3 manual */
+ outb(0x46E8, 0x10); /* Put into setup mode */
+ outb(0x3C3, 0x10);
+ outb(0x102, 0x01); /* Enable registers */
+ outb(0x46E8, 0x08); /* Enable video */
+ outb(0x3C3, 0x08);
+ outb(0x4AE8, 0x00);
+
+#if 0
+ outb(0x42E8, 0x80); /* Reset graphics engine? */
+#endif
+
+ outb(0x3D4, 0x38); /* Unlock all registers */
+ outb(0x3D5, 0x48);
+ outb(0x3D4, 0x39);
+ outb(0x3D5, 0xA5);
+ outb(0x3D4, 0x40);
+ outb(0x3D5, inb(0x3D5)|0x01);
+ outb(0x3D4, 0x33);
+ outb(0x3D5, inb(0x3D5)&~0x52);
+ outb(0x3D4, 0x35);
+ outb(0x3D5, inb(0x3D5)&~0x30);
+ outb(0x3D4, 0x3A);
+ outb(0x3D5, 0x00);
+ outb(0x3D4, 0x53);
+ outb(0x3D5, 0x00);
+ outb(0x3D4, 0x31);
+ outb(0x3D5, inb(0x3D5)&~0x4B);
+ outb(0x3D4, 0x58);
+
+ outb(0x3D5, 0);
+
+ outb(0x3D4, 0x54);
+ outb(0x3D5, 0x38);
+ outb(0x3D4, 0x60);
+ outb(0x3D5, 0x07);
+ outb(0x3D4, 0x61);
+ outb(0x3D5, 0x80);
+ outb(0x3D4, 0x62);
+ outb(0x3D5, 0xA1);
+ outb(0x3D4, 0x69); /* High order bits for cursor address */
+ outb(0x3D5, 0);
+
+ outb(0x3D4, 0x32);
+ outb(0x3D5, inb(0x3D5)&~0x10);
+ } else {
+ outw(0x3c4, 0x0806); /* IBM Portable 860 */
+ outw(0x3c4, 0x1041);
+ outw(0x3c4, 0x1128);
+ outw(0x3d4, 0x4000);
+ outw(0x3d4, 0x3100);
+ outw(0x3d4, 0x3a05);
+ outw(0x3d4, 0x6688);
+ outw(0x3d4, 0x5800); /* disable linear addressing */
+ outw(0x3d4, 0x4500); /* disable H/W cursor */
+ outw(0x3c4, 0x5410); /* enable auto-centering */
+ outw(0x3c4, 0x561f);
+ outw(0x3c4, 0x1b80); /* lock DCLK selection */
+ outw(0x3d4, 0x3900); /* lock S3 registers */
+ outw(0x3d4, 0x3800);
+ } /* endif */
+}
+
+/*
+ * cursor() sets an offset (0-1999) into the 80x25 text area
+ */
+void
+cursor(int x, int y)
+{
+ int pos = (y*cols)+x;
+ outb(0x3D4, 14);
+ outb(0x3D5, pos >> 8);
+ outb(0x3D4, 15);
+ outb(0x3D5, pos);
+}
+
+void
+clearVideoMemory()
+{
+ int i, j;
+ for (i = 0; i < lines; i++) {
+ for (j = 0; j < cols; j++) {
+ vidmem[((i*cols)+j)*2] = 0x20; /* fill with space character */
+ vidmem[((i*cols)+j)*2+1] = 0x07; /* set bg & fg attributes */
+ }
+ }
+}
+
+/* ============ */
+
+
+#define NSLOTS 8
+#define NPCIREGS 5
+
+
+/*
+ should use devfunc number/indirect method to be totally safe on
+ all machines, this works for now on 3 slot Moto boxes
+*/
+
+struct PCI_ConfigInfo {
+ unsigned long * config_addr;
+ unsigned long regs[NPCIREGS];
+} PCI_slots [NSLOTS] = {
+
+ { (unsigned long *)0x80808000, 0xDEADBEEF }, /* onboard */
+ { (unsigned long *)0x80800800, 0xDEADBEEF }, /* onboard */
+ { (unsigned long *)0x80801000, 0xDEADBEEF }, /* onboard */
+ { (unsigned long *)0x80802000, 0xDEADBEEF }, /* onboard */
+ { (unsigned long *)0x80804000, 0xDEADBEEF }, /* onboard */
+ { (unsigned long *)0x80810000, 0xDEADBEEF }, /* slot A/1 */
+ { (unsigned long *)0x80820000, 0xDEADBEEF }, /* slot B/2 */
+ { (unsigned long *)0x80840000, 0xDEADBEEF } /* slot C/3 */
+};
+
+
+
+/*
+ * The following code modifies the PCI Command register
+ * to enable memory and I/O accesses.
+ */
+void
+unlockVideo(int slot)
+{
+ volatile unsigned char * ppci;
+
+ ppci = (unsigned char * )PCI_slots[slot].config_addr;
+ ppci[4] = 0x0003; /* enable memory and I/O accesses */
+ ppci[0x10] = 0x00000; /* turn off memory mapping */
+ ppci[0x11] = 0x00000; /* mem_base = 0 */
+ ppci[0x12] = 0x00000;
+ ppci[0x13] = 0x00000;
+ __asm__ volatile("eieio");
+
+ outb(0x3d4, 0x11);
+ outb(0x3d5, 0x0e); /* unlock CR0-CR7 */
+}
+
+long
+SwapBytes(long lv) /* turn little endian into big indian long */
+{
+ long t;
+ t = (lv&0x000000FF) << 24;
+ t |= (lv&0x0000FF00) << 8;
+ t |= (lv&0x00FF0000) >> 8;
+ t |= (lv&0xFF000000) >> 24;
+ return(t);
+}
+
+
+#define DEVID 0
+#define CMD 1
+#define CLASS 2
+#define MEMBASE 4
+
+int
+scanPCI(int start_slt)
+{
+ int slt, r;
+ struct PCI_ConfigInfo *pslot;
+ int theSlot = -1;
+ int highVgaSlot = 0;
+
+ for ( slt = start_slt + 1; slt < NSLOTS; slt++) {
+ pslot = &PCI_slots[slt];
+ for ( r = 0; r < NPCIREGS; r++) {
+ pslot->regs[r] = SwapBytes ( pslot->config_addr[r] );
+ }
+ /* card in slot ? */
+ if ( pslot->regs[DEVID] != 0xFFFFFFFF ) {
+ /* VGA ? */
+ if ( ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x03000000) ||
+ ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x00010000)) {
+ highVgaSlot = slt;
+ /* did firmware enable it ? */
+ if ( (pslot->regs[CMD] & 0x03) ) {
+ theSlot = slt;
+ break;
+ }
+ }
+ }
+ }
+
+ return ( theSlot );
+}
+
+/* return Vendor ID of card in the slot */
+static
+int PCIVendor(int slotnum) {
+ struct PCI_ConfigInfo *pslot;
+
+ pslot = &PCI_slots[slotnum];
+
+return (pslot->regs[DEVID] & 0xFFFF);
+}
+
+#ifdef DEBUG
+static
+void printslots(void)
+{
+ int i;
+#if 0
+ struct PCI_ConfigInfo *pslot;
+#endif
+ for(i=0; i < NSLOTS; i++) {
+#if 0
+ pslot = &PCI_slots[i];
+ printf("Slot: %d, Addr: %x, Vendor: %08x, Class: %08x\n",
+ i, pslot->config_addr, pslot->regs[0], pslot->regs[2]);
+#else
+ puts("PCI Slot number: "); puthex(i);
+ puts(" Vendor ID: ");
+ puthex(PCIVendor(i)); puts("\n");
+#endif
+ }
+}
+#endif /* DEBUG */
+++ /dev/null
-#!/bin/bash
-
-OFFSET=`grep $1 sImage.map | awk '{print $2}'`
-echo "0x"$OFFSET
+++ /dev/null
-#!/bin/bash
-
-OFFSET=`grep $1 sImage.map | awk '{print $3}'`
-echo "0x"$OFFSET
+++ /dev/null
-#!/bin/bash
-
-OFFSET=`$1 -h $2 | grep $3 | grep -v zvmlinux | awk '{print $3}'`
-echo "0x"$OFFSET
--- /dev/null
+# BK Id: SCCS/s.Makefile 1.5 05/18/01 06:20:29 patch
+#
+#
+# Module name: Makefile
+#
+# Description:
+# Makefile for the IBM "tree" evaluation board Linux kernel
+# boot loaders.
+#
+#
+# Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+#
+# PPC-405 modification
+# Copyright 2000-2001 MontaVista Software Inc.
+# Author: MontaVista Software, Inc.
+# frank_rowand@mvista.com or source@mvista.com
+# debbie_chu@mvista.com
+#
+
+HOSTCFLAGS = -O -I$(TOPDIR)/include
+
+CC = $(CROSS_COMPILE)gcc
+LD = $(CROSS_COMPILE)ld
+OBJCOPY = $(CROSS_COMPILE)objcopy
+OBJDUMP = $(CROSS_COMPILE)objdump
+
+GZIP = gzip -vf9
+RM = rm -f
+MKEVIMG = ../utils/mkevimg -l
+MKIRIMG = ../utils/mkirimg
+LD_ARGS = -e _start -T ld.script -Ttext 0x00200000 -Bstatic
+
+OBJS = ../common/crt0.o main.o misc.o irSect.o ../common/string.o \
+ ../common/misc-common.o
+LIBS = ../lib/zlib.a
+
+treeboot: $(OBJS) $(LIBS) ld.script
+ $(LD) -o $@ $(LD_ARGS) $(OBJS) $(LIBS)
+
+zImage: vmlinux.img
+
+zImage.initrd: vmlinux.initrd.img
+
+treeboot.image: treeboot
+ $(OBJCOPY) --add-section=image=../images/vmlinux.gz treeboot $@
+
+treeboot.initrd: treeboot.image ramdisk.image.gz
+ $(OBJCOPY) --add-section=initrd=ramdisk.image.gz treeboot.image $@
+
+vmlinux.img: treeboot.image
+ $(OBJDUMP) --syms treeboot.image | grep irSectStart > irSectStart.txt
+ $(MKIRIMG) treeboot.image treeboot.image.out irSectStart.txt
+ $(MKEVIMG) treeboot.image.out ../images/vmlinux.tree.img
+ $(RM) treeboot.image treeboot.image.out irSectStart.txt
+
+vmlinux.initrd.img: treeboot.initrd
+ $(OBJDUMP) --all-headers treeboot.initrd | grep irSectStart > irSectStart.txt
+ $(MKIRIMG) treeboot.initrd treeboot.initrd.out irSectStart.txt
+ $(MKEVIMG) treeboot.initrd.out ../images/vmlinux.tree.initrd.img
+ $(RM) treeboot.initrd treeboot.initrd.out irSectStart.txt
+
+clean:
+ rm -f treeboot treeboot.image treeboot.initrd irSectStart.txt vmlinux.*
+
+include $(TOPDIR)/Rules.make
--- /dev/null
+/*
+ * BK Id: SCCS/s.irSect.c 1.6 05/18/01 15:17:22 cort
+ */
+/*
+ *
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *
+ * Module name: irSect.c
+ *
+ * Description:
+ * Defines variables to hold the absolute starting address and size
+ * of the Linux kernel "image" and the initial RAM disk "initrd"
+ * sections within the boot loader.
+ *
+ */
+
+#include "irSect.h"
+
+
+/*
+ * The order of globals below must not change. If more globals are added,
+ * you must change the script 'mkirimg' accordingly.
+ *
+ */
+
+/*
+ * irSectStart must be at beginning of file
+ */
+unsigned int irSectStart = 0xdeadbeaf;
+
+unsigned int imageSect_start = 0;
+unsigned int imageSect_size = 0;
+unsigned int initrdSect_start = 0;
+unsigned int initrdSect_size = 0;
+
+/*
+ * irSectEnd must be at end of file
+ */
+unsigned int irSectEnd = 0xdeadbeaf;
--- /dev/null
+/*
+ * BK Id: SCCS/s.irSect.h 1.6 05/18/01 15:17:22 cort
+ */
+/*
+ *
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *
+ * Module name: irSect.h
+ *
+ * Description:
+ * Defines variables to hold the absolute starting address and size
+ * of the Linux kernel "image" and the initial RAM disk "initrd"
+ * sections within the boot loader.
+ *
+ */
+
+#ifndef __IRSECT_H__
+#define __IRSECT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern unsigned int imageSect_start;
+extern unsigned int imageSect_size;
+
+extern unsigned int initrdSect_start;
+extern unsigned int initrdSect_size;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __IRSECT_H__ */
--- /dev/null
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) } =0
+ .plt : { *(.plt) }
+ .text :
+ {
+ *(.text)
+ *(.rodata)
+ *(.rodata1)
+ *(.got1)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+ _etext = .;
+ PROVIDE (etext = .);
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x0FFF) & 0xFFFFF000;
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.got.plt) *(.got)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
+
--- /dev/null
+/*
+ * BK Id: SCCS/s.main.c 1.7 05/18/01 06:20:29 patch
+ */
+/*
+ * Copyright (c) 1997 Paul Mackerras <paulus@cs.anu.edu.au>
+ * Initial Power Macintosh COFF version.
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ * Modifications for an ELF-based IBM evaluation board version.
+ * Copyright 2000-2001 MontaVista Software Inc.
+ * PPC405GP modifications
+ * Author: MontaVista Software, Inc.
+ * frank_rowand@mvista.com or source@mvista.com
+ * debbie_chu@mvista.com
+ *
+ * Module name: main.c
+ *
+ * Description:
+ * This module does most of the real work for the boot loader. It
+ * checks the variables holding the absolute start address and size
+ * of the Linux kernel "image" and initial RAM disk "initrd" sections
+ * and if they are present, moves them to their "proper" locations.
+ *
+ * For the Linux kernel, "proper" is physical address 0x00000000.
+ * For the RAM disk, "proper" is the image's size below the top
+ * of physical memory. The Linux kernel may be in either raw
+ * binary form or compressed with GNU zip (aka gzip).
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/config.h>
+#include <asm/ppc4xx.h>
+
+#include "nonstdio.h"
+#include "irSect.h"
+#if defined(CONFIG_SERIAL_CONSOLE)
+#include "ns16550.h"
+#endif /* CONFIG_SERIAL_CONSOLE */
+
+
+/* Preprocessor Defines */
+
+/*
+ * Location of the IBM boot ROM function pointer address for retrieving
+ * the board information structure.
+ */
+
+#define BOARD_INFO_VECTOR 0xFFFE0B50
+
+/*
+ * Warning: the board_info doesn't contain valid data until get_board_info()
+ * gets called in start().
+ */
+#define RAM_SIZE board_info.bi_memsize
+
+#define RAM_PBASE 0x00000000
+#define RAM_PEND (RAM_PBASE + RAM_SIZE)
+
+#define RAM_VBASE 0xC0000000
+#define RAM_VEND (RAM_VBASE + RAM_SIZE)
+
+#define RAM_START RAM_PBASE
+#define RAM_END RAM_PEND
+#define RAM_FREE (imageSect_start + imageSect_size + initrdSect_size)
+
+#define PROG_START RAM_START
+
+
+/* Function Macros */
+
+#define ALIGN_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1))
+
+#define stringify(s) tostring(s)
+#define tostring(s) #s
+
+#define mtdcr(rn, v) asm volatile("mtdcr " stringify(rn) ",%0" : : "r" (v))
+#define mfdcr(rn) ({unsigned int rval; \
+ asm volatile("mfdcr %0," stringify(rn) \
+ : "=r" (rval)); rval;})
+#define DCRN_MALCR 0x180 /* MAL Configuration */
+#define MALCR_SR 0x80000000 /* Software Reset */
+
+/* Global Variables */
+
+/* Needed by zalloc and zfree for allocating memory */
+
+char *avail_ram; /* Indicates start of RAM available for heap */
+char *end_avail; /* Indicates end of RAM available for heap */
+
+bd_t board_info;
+
+/*
+ * XXX - Until either the IBM boot ROM provides a way of passing arguments to
+ * the program it launches or until I/O is working in the boot loader,
+ * this is a good spot to pass in command line arguments to the kernel
+ * (e.g. console=tty0).
+ */
+
+
+/*
+** The bootrom may change bootrom_cmdline to point to a buffer in the
+** bootrom.
+*/
+char *bootrom_cmdline = "";
+char treeboot_bootrom_cmdline[512];
+
+#ifdef CONFIG_CMDLINE
+char *cmdline = CONFIG_CMDLINE;
+#else
+char *cmdline = "";
+#endif
+
+/* Function Prototypes */
+
+extern void *zalloc(void *x, unsigned items, unsigned size);
+
+/* serial I/O functions.
+ * These should have generic names, although this is similar to 16550....
+ */
+static volatile unsigned char *uart0_lsr = (unsigned char *)0xef600305;
+static volatile unsigned char *uart0_xcvr = (unsigned char *)0xef600300;
+
+void
+serial_putc(void *unused, unsigned char c)
+{
+ while ((*uart0_lsr & LSR_THRE) == 0);
+ *uart0_xcvr = c;
+}
+
+unsigned char
+serial_getc(void *unused)
+{
+ while ((*uart0_lsr & LSR_DR) == 0);
+ return (*uart0_xcvr);
+}
+
+int
+serial_tstc(void *unused)
+{
+ return ((*uart0_lsr & LSR_DR) != 0);
+}
+
+
+void start(void)
+{
+ void *options;
+ int ns, oh, i;
+ unsigned long sa, len;
+ void *dst;
+ unsigned char *im;
+ unsigned long initrd_start, initrd_size;
+ bd_t *(*get_board_info)(void) =
+ (bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR);
+ bd_t *bip = NULL;
+ volatile unsigned long *em0mr0 = (long *)0xEF600800; /* ftr fixup */
+
+
+
+#if defined(CONFIG_WALNUT)
+ /* turn off ethernet */
+ /* This is to fix a problem with early walnut bootrom. */
+
+ mtdcr(DCRN_MALCR, MALCR_SR); /* 1st reset MAL */
+
+ while (mfdcr(DCRN_MALCR) & MALCR_SR) {}; /* wait for the reset */
+
+ *em0mr0 = 0x20000000; /* then reset EMAC */
+#endif
+
+
+#if 0
+ /* ftr revisit - remove printf()s */
+
+ printf("\n\nbootrom_cmdline = >%s<\n\n", bootrom_cmdline);
+ if (*bootrom_cmdline != '\0') {
+ printf("bootrom_cmdline != NULL, copying it into cmdline\n\n");
+ *treeboot_bootrom_cmdline = '\0';
+ strcat(treeboot_bootrom_cmdline, bootrom_cmdline);
+ cmdline = treeboot_bootrom_cmdline;
+ }
+#endif
+
+
+ if ((bip = get_board_info()) != NULL)
+ memcpy(&board_info, bip, sizeof(bd_t));
+
+ /* Init RAM disk (initrd) section */
+
+ if (initrdSect_start != 0 && (initrd_size = initrdSect_size) != 0) {
+ initrd_start = (RAM_END - initrd_size) & ~0xFFF;
+
+ _printk("Initial RAM disk at 0x%08x (%u bytes)\n",
+ initrd_start, initrd_size);
+
+ memcpy((char *)initrd_start,
+ (char *)(initrdSect_start),
+ initrdSect_size);
+
+ end_avail = (char *)initrd_start;
+ } else {
+ initrd_start = initrd_size = 0;
+ end_avail = (char *)RAM_END;
+ }
+
+ /* Linux kernel image section */
+
+ im = (unsigned char *)(imageSect_start);
+ len = imageSect_size;
+ dst = (void *)PROG_START;
+
+ /* Check for the gzip archive magic numbers */
+
+ if (im[0] == 0x1f && im[1] == 0x8b) {
+
+ /* The gunzip routine needs everything nice and aligned */
+
+ void *cp = (void *)ALIGN_UP(RAM_FREE, 8);
+ avail_ram = (void *)(cp + ALIGN_UP(len, 8)); /* used by zalloc() */
+ memcpy(cp, im, len);
+
+ /* I'm not sure what the 0x200000 parameter is for, but it works. */
+ /* It tells gzip the end of the area you wish to reserve, and it
+ * can use data past that point....unfortunately, this value
+ * isn't big enough (luck ran out). -- Dan
+ */
+
+ gunzip(dst, 0x400000, cp, (int *)&len);
+ } else {
+ memmove(dst, im, len);
+ }
+
+
+ flush_cache(dst, len);
+
+ sa = (unsigned long)dst;
+
+ (*(void (*)())sa)(&board_info,
+ initrd_start,
+ initrd_start + initrd_size,
+ cmdline,
+ cmdline + strlen(cmdline));
+
+ pause();
+}
--- /dev/null
+/*
+ * BK Id: SCCS/s.misc.S 1.7 05/18/01 06:20:29 patch
+ */
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include "../../kernel/ppc_asm.tmpl"
+
+ .text
+
+/*
+ * Flush the dcache and invalidate the icache for a range of addresses.
+ *
+ * flush_cache(addr, len)
+ */
+ .global flush_cache
+flush_cache:
+ mfpvr r5 # Get processor version register
+ extrwi r5,r5,16,0 # Get the version bits
+ cmpwi cr0,r5,0x0020 # Is this a 403-based processor?
+ beq 1f # Yes, it is
+ li r5,32 # It is not a 403, set to 32 bytes
+ addi r4,r4,32-1 # len += line_size - 1
+ srwi. r4,r4,5 # Convert from bytes to lines
+ b 2f
+1: li r5,16 # It is a 403, set to 16 bytes
+ addi r4,r4,16-1 # len += line_size - 1
+ srwi. r4,r4,4 # Convert from bytes to lines
+2: mtctr r4 # Set-up the counter register
+ beqlr # If it is 0, we are done
+3: dcbf r0,r3 # Flush and invalidate the data line
+ icbi r0,r3 # Invalidate the instruction line
+ add r3,r3,r5 # Move to the next line
+ bdnz 3b # Are we done yet?
+ sync
+ isync
+ blr # Return to the caller
--- /dev/null
+#
+# arch/ppc/boot/utils/Makefile
+#
+# 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.
+
+HOSTCFLAGS += -I$(TOPDIR)/arch/$(ARCH)/boot/include
+
+# Simple programs with 1 file and no extra CFLAGS
+UTILS = addnote hack-coff mkprep mksimage mknote piggyback mkpmon mkbugboot
+
+$(UTILS):
+ $(HOSTCC) $(HOSTCFLAGS) -o $@ $@.c
+
+clean:
+ rm -f $(UTILS)
+
+include $(TOPDIR)/Rules.make
--- /dev/null
+/*
+ * BK Id: SCCS/s.addnote.c 1.7 05/18/01 15:17:23 cort
+ */
+/*
+ * Program to hack in a PT_NOTE program header entry in an ELF file.
+ * This is needed for OF on RS/6000s to load an image correctly.
+ * Note that OF needs a program header entry for the note, not an
+ * ELF section.
+ *
+ * Copyright 2000 Paul Mackerras.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Usage: addnote zImage
+ */
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+char arch[] = "PowerPC";
+
+#define N_DESCR 6
+unsigned int descr[N_DESCR] = {
+#if 1
+ /* values for IBM RS/6000 machines */
+ 0xffffffff, /* real-mode = true */
+ 0x00c00000, /* real-base, i.e. where we expect OF to be */
+ 0xffffffff, /* real-size */
+ 0xffffffff, /* virt-base */
+ 0xffffffff, /* virt-size */
+ 0x4000, /* load-base */
+#else
+ /* values for longtrail CHRP */
+ 0, /* real-mode = false */
+ 0xffffffff, /* real-base */
+ 0xffffffff, /* real-size */
+ 0xffffffff, /* virt-base */
+ 0xffffffff, /* virt-size */
+ 0x00600000, /* load-base */
+#endif
+};
+
+unsigned char buf[512];
+
+#define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1]))
+#define GET_32BE(off) ((GET_16BE(off) << 16) + GET_16BE((off)+2))
+
+#define PUT_16BE(off, v) (buf[off] = ((v) >> 8) & 0xff, \
+ buf[(off) + 1] = (v) & 0xff)
+#define PUT_32BE(off, v) (PUT_16BE((off), (v) >> 16), \
+ PUT_16BE((off) + 2, (v)))
+
+/* Structure of an ELF file */
+#define E_IDENT 0 /* ELF header */
+#define E_PHOFF 28
+#define E_PHENTSIZE 42
+#define E_PHNUM 44
+#define E_HSIZE 52 /* size of ELF header */
+
+#define EI_MAGIC 0 /* offsets in E_IDENT area */
+#define EI_CLASS 4
+#define EI_DATA 5
+
+#define PH_TYPE 0 /* ELF program header */
+#define PH_OFFSET 4
+#define PH_FILESZ 16
+#define PH_HSIZE 32 /* size of program header */
+
+#define PT_NOTE 4 /* Program header type = note */
+
+#define ELFCLASS32 1
+#define ELFDATA2MSB 2
+
+unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' };
+
+int main(int ac, char **av)
+{
+ int fd, n, i;
+ int ph, ps, np;
+ int nnote, ns;
+
+ if (ac != 2) {
+ fprintf(stderr, "Usage: %s elf-file\n", av[0]);
+ exit(1);
+ }
+ fd = open(av[1], O_RDWR);
+ if (fd < 0) {
+ perror(av[1]);
+ exit(1);
+ }
+
+ nnote = strlen(arch) + 1 + (N_DESCR + 3) * 4;
+
+ n = read(fd, buf, sizeof(buf));
+ if (n < 0) {
+ perror("read");
+ exit(1);
+ }
+
+ if (n < E_HSIZE || memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0)
+ goto notelf;
+
+ if (buf[E_IDENT+EI_CLASS] != ELFCLASS32
+ || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) {
+ fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n",
+ av[1]);
+ exit(1);
+ }
+
+ ph = GET_32BE(E_PHOFF);
+ ps = GET_16BE(E_PHENTSIZE);
+ np = GET_16BE(E_PHNUM);
+ if (ph < E_HSIZE || ps < PH_HSIZE || np < 1)
+ goto notelf;
+ if (ph + (np + 1) * ps + nnote > n)
+ goto nospace;
+
+ for (i = 0; i < np; ++i) {
+ if (GET_32BE(ph + PH_TYPE) == PT_NOTE) {
+ fprintf(stderr, "%s already has a note entry\n",
+ av[1]);
+ exit(0);
+ }
+ ph += ps;
+ }
+
+ /* XXX check that the area we want to use is all zeroes */
+ for (i = 0; i < ps + nnote; ++i)
+ if (buf[ph + i] != 0)
+ goto nospace;
+
+ /* fill in the program header entry */
+ ns = ph + ps;
+ PUT_32BE(ph + PH_TYPE, PT_NOTE);
+ PUT_32BE(ph + PH_OFFSET, ns);
+ PUT_32BE(ph + PH_FILESZ, nnote);
+
+ /* fill in the note area we point to */
+ /* XXX we should probably make this a proper section */
+ PUT_32BE(ns, strlen(arch) + 1);
+ PUT_32BE(ns + 4, N_DESCR * 4);
+ PUT_32BE(ns + 8, 0x1275);
+ strcpy(&buf[ns + 12], arch);
+ ns += 12 + strlen(arch) + 1;
+ for (i = 0; i < N_DESCR; ++i)
+ PUT_32BE(ns + i * 4, descr[i]);
+
+ /* Update the number of program headers */
+ PUT_16BE(E_PHNUM, np + 1);
+
+ /* write back */
+ lseek(fd, (long) 0, SEEK_SET);
+ i = write(fd, buf, n);
+ if (i < 0) {
+ perror("write");
+ exit(1);
+ }
+ if (i < n) {
+ fprintf(stderr, "%s: write truncated\n", av[1]);
+ exit(1);
+ }
+
+ exit(0);
+
+ notelf:
+ fprintf(stderr, "%s does not appear to be an ELF file\n", av[0]);
+ exit(1);
+
+ nospace:
+ fprintf(stderr, "sorry, I can't find space in %s to put the note\n",
+ av[0]);
+ exit(1);
+}
--- /dev/null
+#
+# ELF header field numbers
+#
+
+$e_ident = 0; # Identification bytes / magic number
+$e_type = 1; # ELF file type
+$e_machine = 2; # Target machine type
+$e_version = 3; # File version
+$e_entry = 4; # Start address
+$e_phoff = 5; # Program header file offset
+$e_shoff = 6; # Section header file offset
+$e_flags = 7; # File flags
+$e_ehsize = 8; # Size of ELF header
+$e_phentsize = 9; # Size of program header
+$e_phnum = 10; # Number of program header entries
+$e_shentsize = 11; # Size of section header
+$e_shnum = 12; # Number of section header entries
+$e_shstrndx = 13; # Section header table string index
+
+#
+# Section header field numbers
+#
+
+$sh_name = 0; # Section name
+$sh_type = 1; # Section header type
+$sh_flags = 2; # Section header flags
+$sh_addr = 3; # Virtual address
+$sh_offset = 4; # File offset
+$sh_size = 5; # Section size
+$sh_link = 6; # Miscellaneous info
+$sh_info = 7; # More miscellaneous info
+$sh_addralign = 8; # Memory alignment
+$sh_entsize = 9; # Entry size if this is a table
--- /dev/null
+/*
+ * BK Id: SCCS/s.hack-coff.c 1.8 05/18/01 06:20:29 patch
+ */
+/*
+ * hack-coff.c - hack the header of an xcoff file to fill in
+ * a few fields needed by the Open Firmware xcoff loader on
+ * Power Macs but not initialized by objcopy.
+ *
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "rs6000.h"
+
+#define AOUT_MAGIC 0x010b
+
+#define get_16be(x) ((((unsigned char *)(x))[0] << 8) \
+ + ((unsigned char *)(x))[1])
+#define put_16be(x, v) (((unsigned char *)(x))[0] = (v) >> 8, \
+ ((unsigned char *)(x))[1] = (v) & 0xff)
+#define get_32be(x) ((((unsigned char *)(x))[0] << 24) \
+ + (((unsigned char *)(x))[1] << 16) \
+ + (((unsigned char *)(x))[2] << 8) \
+ + ((unsigned char *)(x))[3])
+
+int
+main(int ac, char **av)
+{
+ int fd;
+ int i, nsect;
+ int aoutsz;
+ struct external_filehdr fhdr;
+ AOUTHDR aout;
+ struct external_scnhdr shdr;
+
+ if (ac != 2) {
+ fprintf(stderr, "Usage: hack-coff coff-file\n");
+ exit(1);
+ }
+ if ((fd = open(av[1], 2)) == -1) {
+ perror(av[2]);
+ exit(1);
+ }
+ if (read(fd, &fhdr, sizeof(fhdr)) != sizeof(fhdr))
+ goto readerr;
+ i = get_16be(fhdr.f_magic);
+ if (i != U802TOCMAGIC && i != U802WRMAGIC && i != U802ROMAGIC) {
+ fprintf(stderr, "%s: not an xcoff file\n", av[1]);
+ exit(1);
+ }
+ aoutsz = get_16be(fhdr.f_opthdr);
+ if (read(fd, &aout, aoutsz) != aoutsz)
+ goto readerr;
+ nsect = get_16be(fhdr.f_nscns);
+ for (i = 0; i < nsect; ++i) {
+ if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr))
+ goto readerr;
+ if (strcmp(shdr.s_name, ".text") == 0) {
+ put_16be(aout.o_snentry, i+1);
+ put_16be(aout.o_sntext, i+1);
+ } else if (strcmp(shdr.s_name, ".data") == 0) {
+ put_16be(aout.o_sndata, i+1);
+ } else if (strcmp(shdr.s_name, ".bss") == 0) {
+ put_16be(aout.o_snbss, i+1);
+ }
+ }
+ put_16be(aout.magic, AOUT_MAGIC);
+ if (lseek(fd, (long) sizeof(struct external_filehdr), 0) == -1
+ || write(fd, &aout, aoutsz) != aoutsz) {
+ fprintf(stderr, "%s: write error\n", av[1]);
+ exit(1);
+ }
+ close(fd);
+ exit(0);
+
+readerr:
+ fprintf(stderr, "%s: read error or file too short\n", av[1]);
+ exit(1);
+}
--- /dev/null
+#!/usr/bin/perl
+
+#
+# Copyright (c) 1998-1999 TiVo, Inc.
+# All rights reserved.
+#
+# Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+# Major syntactic and usability rework.
+#
+# Module name: mkevimg
+#
+# Description:
+# Converts an ELF output file from the linker into the format used by
+# the IBM evaluation board ROM Monitor to load programs from a host
+# onto the evaluation board. The ELF file must be an otherwise execut-
+# able file (with the text and data addresses bound at link time) and
+# have space reserved after the entry point for the load information
+# block:
+#
+# typedef struct boot_block {
+# unsigned long magic; 0x0052504F
+# unsigned long dest; Target address of the image
+# unsigned long num_512blocks; Size, rounded-up, in 512 byte blocks
+# unsigned long debug_flag; Run the debugger or image after load
+# unsigned long entry_point; The image address to jump to after load
+# unsigned long reserved[3];
+# } boot_block_t;
+#
+#
+
+use File::Basename;
+use Getopt::Std;
+
+#
+# usage()
+#
+# Description:
+# This routine prints out the proper command line usage for this program
+#
+# Input(s):
+# status - Flag determining what usage information will be printed and what
+# the exit status of the program will be after the information is
+# printed.
+#
+# Output(s):
+# N/A
+#
+# Returns:
+# This subroutine does not return.
+#
+
+sub usage {
+ my($status);
+ $status = $_[0];
+
+ printf("Usage: %s [-hlvV] <ELF input file> <Evaluation board output file>\n",
+ $program);
+
+ if ($status != 0) {
+ printf("Try `%s -h' for more information.\n", $program);
+ }
+
+ if ($status != 1) {
+ print(" -h Print out this message and exit.\n");
+ print(" -l Linux mode; if present, copy 'image' and 'initrd' sections.\n");
+ print(" -v Verbose. Print out lots of ELF information.\n");
+ print(" -V Print out version information and exit.\n");
+ }
+
+ exit($status);
+}
+
+#
+# version()
+#
+# Description:
+# This routine prints out program version information
+#
+# Input(s):
+# N/A
+#
+# Output(s):
+# N/A
+#
+# Returns:
+# This subroutine does not return.
+#
+
+sub version {
+ print("mkevimg Version 1.1.0\n");
+ print("Copyright (c) 1998-1999 TiVo, Inc.\n");
+ print("Copyright (c) 1999 Grant Erickson <grant\@lcse.umn.edu>\n");
+
+ exit (0);
+}
+
+#
+# file_check()
+#
+# Description:
+# This routine checks an input file to ensure that it exists, is a
+# regular file, and is readable.
+#
+# Input(s):
+# file - Input file to be checked.
+#
+# Output(s):
+# N/A
+#
+# Returns:
+# 0 if the file exists, is a regular file, and is readable, otherwise -1.
+#
+
+sub file_check {
+ my($file);
+ $file = $_[0];
+
+ if (!(-e $file)) {
+ printf("The file \"%s\" does not exist.\n", $file);
+ return (-1);
+ } elsif (!(-f $file)) {
+ printf("The file \"%s\" is not a regular file.\n", $file);
+ return (-1);
+ } elsif (!(-r $file)) {
+ printf("The file \"%s\" is not readable.\n", $file);
+ return (-1);
+ }
+
+ return (0);
+}
+
+#
+# decode_options()
+#
+# Description:
+# This routine steps through the command-line arguments, parsing out
+# recognzied options.
+#
+# Input(s):
+# N/A
+#
+# Output(s):
+# N/A
+#
+# Returns:
+# N/A
+#
+
+sub decode_options {
+
+ if (!getopts("hlvV")) {
+ usage(1);
+ }
+
+ if ($opt_h) {
+ usage(0);
+ }
+
+ if ($opt_l) {
+ $linux = 1;
+ }
+
+ if ($opt_V) {
+ version();
+ exit (0);
+ }
+
+ if ($opt_v) {
+ $verbose = 1;
+ }
+
+ if (!($ifile = shift(@ARGV))) {
+ usage(1);
+ }
+
+ if (!($ofile = shift(@ARGV))) {
+ usage (1);
+ }
+
+ if (file_check($ifile)) {
+ exit(1);
+ }
+
+}
+
+#
+# ELF file and section header field numbers
+#
+
+require '../utils/elf.pl';
+
+#
+# Main program body
+#
+
+{
+ $program = basename($0);
+
+ decode_options();
+
+ open(ELF, "<$ifile") || die "Cannot open input file";
+
+ $ifilesize = (-s $ifile);
+
+ if ($verbose) {
+ print("Output file: $ofile\n");
+ print("Input file: $ifile, $ifilesize bytes.\n");
+ }
+
+ if (read(ELF, $ibuf, $ifilesize) != $ifilesize) {
+ print("Failed to read input file!\n");
+ exit(1);
+ }
+
+ #
+ # Parse ELF header
+ #
+
+ @eh = unpack("a16n2N5n6", $ibuf);
+
+ #
+ # Make sure this is actually a PowerPC ELF file.
+ #
+
+ if (substr($eh[$e_ident], 0, 4) ne "\177ELF") {
+ printf("The file \"%s\" is not an ELF file.\n", $ifile);
+ exit (1);
+ } elsif ($eh[$e_machine] != 20) {
+ printf("The file \"%s\" is not a PowerPC ELF file.\n", $ifile);
+ exit (1);
+ }
+
+ if ($verbose) {
+ print("File header:\n");
+ printf(" Identifier: %s\n", $eh[$e_ident]);
+ printf(" Type: %d\n", $eh[$e_type]);
+ printf(" Machine: %d\n", $eh[$e_machine]);
+ printf(" Version: %d\n", $eh[$e_version]);
+ printf(" Entry point: 0x%08x\n", $eh[$e_entry]);
+ printf(" Program header offset: 0x%x\n", $eh[$e_phoff]);
+ printf(" Section header offset: 0x%x\n", $eh[$e_shoff]);
+ printf(" Flags: 0x%08x\n", $eh[$e_flags]);
+ printf(" Header size: %d\n", $eh[$e_ehsize]);
+ printf(" Program entry size: %d\n", $eh[$e_phentsize]);
+ printf(" Program table entries: %d\n", $eh[$e_phnum]);
+ printf(" Section header size: %d\n", $eh[$e_shentsize]);
+ printf(" Section table entries: %d\n", $eh[$e_shnum]);
+ printf(" String table section: %d\n", $eh[$e_shstrndx]);
+ }
+
+ #
+ # Find the section header for the string table.
+ #
+
+ $strtable_section_offset = $eh[$e_shoff] +
+ $eh[$e_shstrndx] * $eh[$e_shentsize];
+
+ if ($verbose) {
+ printf("String table section header offset: 0x%x\n",
+ $strtable_section_offset);
+ }
+
+ #
+ # Find the start of the string table.
+ #
+
+ @strh = unpack("N10", substr($ibuf, $strtable_section_offset,
+ $eh[$e_shentsize]));
+
+ if ($verbose) {
+ printf("Section name strings start at: 0x%x, %d bytes.\n",
+ $strh[$sh_offset], $strh[$sh_size]);
+ }
+
+ $names = substr($ibuf, $strh[$sh_offset], $strh[$sh_size]);
+
+ # Grab each section header and find '.text' and '.bss' sections in
+ # particular.
+
+ if ($verbose) {
+ print("Section headers:\n");
+ print("Idx Name Size Address File off Algn\n");
+ print("--- ------------------------ -------- -------- -------- ----\n");
+ }
+
+ $off = $eh[$e_shoff];
+
+ for($i = 0; $i < $eh[$e_shnum]; $i++, $off += $eh[$e_shentsize]) {
+ @sh = unpack("N10", substr($ibuf, $off, $eh[$e_shentsize]));
+
+ # Take the first section name from the array returned by split.
+
+ ($name) = split(/\000/, substr($names, $sh[$sh_name]));
+
+ if ($verbose) {
+ printf("%3d %-24s %8x %08x %08x %4d\n",
+ $i, $name, $sh[$sh_size], $sh[$sh_addr],
+ $sh[$sh_offset], $sh[$sh_addralign]);
+ }
+
+ # Attempt to find the .text and .bss sections
+
+ if ($name =~ /^\.bss$/) {
+ ($bss_addr, $bss_offset, $bss_size) =
+ ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+
+ } elsif ($name =~ /^\.text$/) {
+ ($text_addr, $text_offset, $text_size) =
+ ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+
+ } elsif ($linux && ($name =~ /^\image$/)) {
+ $image_found = 1;
+
+ ($image_addr, $image_offset, $image_size) =
+ ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+
+ } elsif ($linux && ($name =~ /^\initrd$/)) {
+ $initrd_found = 1;
+
+ ($initrd_addr, $initrd_offset, $initrd_size) =
+ ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+
+ }
+ }
+
+ printf("Text section - Address: 0x%08x, Size: 0x%08x\n",
+ $text_addr, $text_size);
+ printf("Bss section - Address: 0x%08x, Size: 0x%08x\n",
+ $bss_addr, $bss_size);
+
+ if ($linux) {
+ if ($image_found) {
+ printf("Image section - Address: 0x%08x, Size: 0x%08x\n",
+ $image_addr, $image_size);
+ }
+
+ if ($initrd_found) {
+ printf("Initrd section - Address: 0x%08x, Size: 0x%08x\n",
+ $initrd_addr, $initrd_size);
+ }
+ }
+
+ #
+ # Open output file
+ #
+
+ open(BOOT, ">$ofile") || die "Cannot open output file";
+
+ #
+ # Compute image size
+ #
+
+ $output_size = $bss_offset - $text_offset + $bss_size;
+
+ if ($linux && $image_found) {
+ $output_size += $image_size;
+ }
+
+ if ($linux && $initrd_found) {
+ $output_size += $initrd_size;
+ }
+
+ $num_blocks = $output_size / 512 + 1;
+
+ #
+ # Write IBM PowerPC evaluation board boot_block_t header
+ #
+
+ $header = pack("H8N7", "0052504f", $text_addr, $num_blocks, 0,
+ $text_addr, 0, 0, 0);
+
+ $bytes = length($header);
+
+ if (($resid = syswrite(BOOT, $header, $bytes)) != $bytes) {
+ die("Could not write boot image header to output file.");
+ }
+
+ printf("Entry point = 0x%08x\n", $text_addr);
+ printf("Image size = 0x%08x (%d bytes) (%d blocks).\n",
+ $output_size, $output_size, $num_blocks);
+
+ #
+ # Write image starting after ELF and program headers and
+ # continuing to beginning of bss
+ #
+
+ $bytes = $bss_offset - $text_offset + $bss_size;
+
+ if (($resid = syswrite(BOOT, $ibuf, $bytes, $text_offset)) != $bytes) {
+ die("Could not write boot image to output file.\n");
+ }
+
+ #
+ # If configured, write out the image and initrd sections as well
+ #
+
+ if ($linux) {
+ if ($image_found) {
+ $bytes = $image_size;
+ if (($resid = syswrite(BOOT, $ibuf, $bytes, $image_offset)) != $bytes) {
+ die("Could not write boot image to output file.\n");
+ }
+ }
+
+ if ($initrd_found) {
+ $bytes = $initrd_size;
+ if (($resid = syswrite(BOOT, $ibuf, $bytes, $initrd_offset)) != $bytes) {
+ die("Could not write boot image to output file.\n");
+ }
+ }
+ }
+
+ #
+ # Pad to a multiple of 512 bytes
+ #
+
+ $pad_size = 512 - (length($header) + $output_size) % 512;
+
+ if ($verbose) {
+ print("Padding boot image by an additional $pad_size bytes.\n");
+ }
+
+ $pad_string = pack(("H8","deadbeef") x 128);
+
+ syswrite(BOOT, $pad_string, $pad_size) or
+ die "Could not pad boot image in output file.\n";
+
+ #
+ # Clean-up and leave
+ #
+
+ close(BOOT);
+
+ print("\nBoot image file \"$ofile\" built successfully.\n\n");
+
+ exit(0);
+}
--- /dev/null
+#!/usr/bin/perl
+#
+# Copyright (c) 1998-1999 TiVo, Inc.
+# Original ELF parsing code.
+#
+# Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+# Original code from 'mkevimg'.
+#
+# Module name: mkirimg
+#
+# Description:
+# Reads an ELF file and assigns global variables 'imageSect_start',
+# 'imageSect_size', 'initrdSect_start', and 'initrdSect_size' from
+# the "image" and "initrd" section header information. It then
+# rewrites the input ELF file with assigned globals to an output
+# file.
+#
+# An input file, "irSectStart.txt" has the memory address of
+# 'irSectStart'. The irSectStart memory address is used to find
+# the global variables in the ".data" section of the ELF file.
+# The 'irSectStart' and the above global variables are defined
+# in "irSect.c".
+#
+#
+
+use File::Basename;
+use Getopt::Std;
+
+#
+# usage()
+#
+# Description:
+# This routine prints out the proper command line usage for this program
+#
+# Input(s):
+# status - Flag determining what usage information will be printed and what
+# the exit status of the program will be after the information is
+# printed.
+#
+# Output(s):
+# N/A
+#
+# Returns:
+# This subroutine does not return.
+#
+
+sub usage {
+ my($status);
+ $status = $_[0];
+
+ printf("Usage: %s [-hvV] <ELF input file> <Evaluation board output file> <irSectStart.txt file>\n",
+ $program);
+
+ if ($status != 0) {
+ printf("Try `%s -h' for more information.\n", $program);
+ }
+
+ if ($status != 1) {
+ print(" -h Print out this message and exit.\n");
+ print(" -v Verbose. Print out lots of ELF information.\n");
+ print(" -V Print out version information and exit.\n");
+ }
+
+ exit($status);
+}
+
+#
+# version()
+#
+# Description:
+# This routine prints out program version information
+#
+# Input(s):
+# N/A
+#
+# Output(s):
+# N/A
+#
+# Returns:
+# This subroutine does not return.
+#
+
+sub version {
+ print("mkirimg Version 1.1.0\n");
+ print("Copyright (c) 1998-1999 TiVo, Inc.\n");
+ print("Copyright (c) 1999 Grant Erickson <grant\@lcse.umn.edu>\n");
+
+ exit (0);
+}
+
+#
+# file_check()
+#
+# Description:
+# This routine checks an input file to ensure that it exists, is a
+# regular file, and is readable.
+#
+# Input(s):
+# file - Input file to be checked.
+#
+# Output(s):
+# N/A
+#
+# Returns:
+# 0 if the file exists, is a regular file, and is readable, otherwise -1.
+#
+
+sub file_check {
+ my($file);
+ $file = $_[0];
+
+ if (!(-e $file)) {
+ printf("The file \"%s\" does not exist.\n", $file);
+ return (-1);
+ } elsif (!(-f $file)) {
+ printf("The file \"%s\" is not a regular file.\n", $file);
+ return (-1);
+ } elsif (!(-r $file)) {
+ printf("The file \"%s\" is not readable.\n", $file);
+ return (-1);
+ }
+
+ return (0);
+}
+
+#
+# decode_options()
+#
+# Description:
+# This routine steps through the command-line arguments, parsing out
+# recognzied options.
+#
+# Input(s):
+# N/A
+#
+# Output(s):
+# N/A
+#
+# Returns:
+# N/A
+#
+
+sub decode_options {
+
+ if (!getopts("hvV")) {
+ usage(1);
+ }
+
+ if ($opt_h) {
+ usage(0);
+ }
+
+ if ($opt_V) {
+ version();
+ exit (0);
+ }
+
+ if ($opt_v) {
+ $verbose = 1;
+ }
+
+ if (!($ElfFile = shift(@ARGV))) {
+ usage(1);
+ }
+
+ if (!($OutputFile = shift(@ARGV))) {
+ usage (1);
+ }
+
+ if (!($IrFile = shift(@ARGV))) {
+ usage (1);
+ }
+
+ if (file_check($ElfFile)) {
+ exit(1);
+ }
+
+ if (file_check($IrFile)) {
+ exit(1);
+ }
+}
+
+#
+# ELF file and section header field numbers
+#
+
+require '../utils/elf.pl';
+
+#
+# Main program body
+#
+
+{
+ $program = basename($0);
+ decode_options();
+
+ open(ELF, "<$ElfFile") || die "Cannot open input file";
+ open(OUTPUT, ">$OutputFile") || die "Cannot open output file";
+ open(IR, "$IrFile") || die "Cannot open input file";
+
+ $ElfFilesize = (-s $ElfFile);
+
+ if (read(ELF, $ibuf, $ElfFilesize) != $ElfFilesize) {
+ print("Failed to read ELF input file!\n");
+ exit(1);
+ }
+
+ if (read(IR, $irbuf, 8) != 8) {
+ print("Failed to read Ir input file!\n");
+ exit(1);
+ }
+
+ #
+ # Parse ELF header
+ #
+
+ @eh = unpack("a16n2N5n6", $ibuf);
+
+ #
+ # Make sure this is actually a PowerPC ELF file.
+ #
+
+ if (substr($eh[$e_ident], 0, 4) ne "\177ELF") {
+ printf("The file \"%s\" is not an ELF file.\n", $ElfFile);
+ exit (1);
+ } elsif ($eh[$e_machine] != 20) {
+ printf("The file \"%s\" is not a PowerPC ELF file.\n", $ElfFile);
+ exit (1);
+ }
+
+ #
+ # Find the section header for the string table.
+ #
+
+ $strtable_section_offset = $eh[$e_shoff] +
+
+ $eh[$e_shstrndx] * $eh[$e_shentsize];
+
+ if ($verbose) {
+ printf("String table section header offset: 0x%x\n",
+ $strtable_section_offset);
+ }
+
+ #
+ # Find the start of the string table.
+ #
+
+ @strh = unpack("N10", substr($ibuf, $strtable_section_offset,
+ $eh[$e_shentsize]));
+
+ if ($verbose) {
+ printf("Section name strings start at: 0x%x, %d bytes.\n",
+ $strh[$sh_offset], $strh[$sh_size]);
+ }
+
+ $names = substr($ibuf, $strh[$sh_offset], $strh[$sh_size]);
+
+ # Grab each section header and find '.data', 'image', and
+ # 'initrd' sections in particular.
+
+ $off = $eh[$e_shoff];
+ $imageFound = 0;
+ $initrdFound = 0;
+
+ for($i = 0; $i < $eh[$e_shnum]; $i++, $off += $eh[$e_shentsize]) {
+ @sh = unpack("N10", substr($ibuf, $off, $eh[$e_shentsize]));
+
+ # Take the first section name from the array returned by split.
+
+ ($name) = split(/\000/, substr($names, $sh[$sh_name]));
+
+ # Attempt to find the .data, image, and initrd sections
+
+ if ($name =~ /^\image$/) {
+ ($image_addr, $image_offset, $image_size) =
+ ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+ $imageFound = 1;
+
+ } elsif ($name =~ /^\initrd$/) {
+ ($initrd_addr, $initrd_offset, $initrd_size) =
+ ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+ $initrdFound = 1;
+
+ } elsif ($name =~ /^\.data$/) {
+ ($data_addr, $data_offset, $data_size) =
+ ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+
+ } elsif ($name =~ /^\.bss$/) {
+ ($bss_addr, $bss_offset, $bss_size) =
+ ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+
+ }
+ }
+
+ if ($verbose) {
+ printf("Data section - Address: 0x%08x, Size: 0x%08x, File Offset 0x%08x\n",
+ $data_addr, $data_size, $data_offset);
+ printf("Bss section - Address: 0x%08x, Size: 0x%08x, File Offset 0x%08x\n",
+ $bss_addr, $bss_size, $bss_offset);
+ }
+
+ if ($verbose) {
+ if ($imageFound) {
+ printf("Image section - Address: 0x%08x, Size: 0x%08x\n",
+ $image_addr, $image_size);
+ } else {
+ printf("Image section not found in file: $ElfFile\n");
+ }
+
+ if ($initrdFound) {
+ printf("Initrd section - Address: 0x%08x, Size: 0x%08x\n",
+ $initrd_addr, $initrd_size);
+ } else {
+ printf("Initrd section not found in file: $ElfFile\n");
+ }
+ }
+
+ # get file offset of irSectStart
+
+ $irSectStartoffset = hex ($irbuf);
+
+ if ($verbose) {
+ printf("irSectStartOffset Address: 0x%08x\n", $irSectStartoffset);
+ }
+
+ # get the offset of global variables
+
+ $initialOffset = ($irSectStartoffset - $data_addr) + $data_offset + 4;
+
+ # write modified values to OUTPUT file
+
+ syswrite(OUTPUT, $ibuf, $initialOffset);
+
+ if ($imageFound) {
+ $testN = pack ("N2", $bss_addr + $bss_size, $image_size);
+ syswrite(OUTPUT, $testN, length($testN));
+ printf("Updated symbol \"imageSect_start\" to 0x%08x\n",
+ $bss_addr + $bss_size);
+ printf("Updated symbol \"imageSect_size\" to 0x%08x\n", $image_size);
+ } else {
+ syswrite(OUTPUT, $ibuf, 8, $initialOffset);
+ }
+
+ if ($initrdFound) {
+ $testN = pack ("N2", $bss_addr + $bss_size + $image_size, $initrd_size);
+ syswrite(OUTPUT, $testN, length($testN));
+ printf("Updated symbol \"initrdSect_start\" to 0x%08x\n",
+ $bss_addr + $bss_size + $image_size);
+ printf("Updated symbol \"initrdSect_size\" to 0x%08x\n", $initrd_size);
+ } else {
+ syswrite(OUTPUT, $ibuf,8, $initialOffset + 8);
+ }
+
+ syswrite(OUTPUT, $ibuf, $ElfFilesize - ($initialOffset + 16),
+ $initialOffset + 16);
+
+ #
+ # Clean-up and leave
+ #
+
+ close (ELF);
+ close (OUTPUT);
+ close (IR);
+
+ exit (0);
+}
+
--- /dev/null
+/*
+ * BK Id: SCCS/s.mknote.c 1.7 05/18/01 15:17:23 cort
+ */
+/*
+ * Copyright (C) Cort Dougan 1999.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Generate a note section as per the CHRP specification.
+ *
+ */
+
+#include <stdio.h>
+
+#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff );
+
+int main(void)
+{
+/* header */
+ /* namesz */
+ PL(strlen("PowerPC")+1);
+ /* descrsz */
+ PL(6*4);
+ /* type */
+ PL(0x1275);
+ /* name */
+ printf("PowerPC"); printf("%c", 0);
+
+/* descriptor */
+ /* real-mode */
+ PL(0xffffffff);
+ /* real-base */
+ PL(0x00c00000);
+ /* real-size */
+ PL(0xffffffff);
+ /* virt-base */
+ PL(0xffffffff);
+ /* virt-size */
+ PL(0xffffffff);
+ /* load-base */
+ PL(0x4000);
+ return 0;
+}
--- /dev/null
+/*
+ * BK Id: SCCS/s.mkprep.c 1.7 05/18/01 06:20:29 patch
+ */
+/*
+ * Makes a prep bootable image which can be dd'd onto
+ * a disk device to make a bootdisk. Will take
+ * as input a elf executable, strip off the header
+ * and write out a boot image as:
+ * 1) default - strips elf header
+ * suitable as a network boot image
+ * 2) -pbp - strips elf header and writes out prep boot partition image
+ * cat or dd onto disk for booting
+ * 3) -asm - strips elf header and writes out as asm data
+ * useful for generating data for a compressed image
+ * -- Cort
+ *
+ * Modified for x86 hosted builds by Matt Porter <porter@neta.com>
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#define cpu_to_le32(x) le32_to_cpu((x))
+unsigned long le32_to_cpu(unsigned long x)
+{
+ return (((x & 0x000000ffU) << 24) |
+ ((x & 0x0000ff00U) << 8) |
+ ((x & 0x00ff0000U) >> 8) |
+ ((x & 0xff000000U) >> 24));
+}
+
+
+#define cpu_to_le16(x) le16_to_cpu((x))
+unsigned short le16_to_cpu(unsigned short x)
+{
+ return (((x & 0x00ff) << 8) |
+ ((x & 0xff00) >> 8));
+}
+
+#define cpu_to_be32(x) (x)
+#define be32_to_cpu(x) (x)
+#define cpu_to_be16(x) (x)
+#define be16_to_cpu(x) (x)
+
+/* size of read buffer */
+#define SIZE 0x1000
+
+
+typedef unsigned long dword_t;
+typedef unsigned short word_t;
+typedef unsigned char byte_t;
+typedef byte_t block_t[512];
+typedef byte_t page_t[4096];
+
+
+/*
+ * Partition table entry
+ * - from the PReP spec
+ */
+typedef struct partition_entry {
+ byte_t boot_indicator;
+ byte_t starting_head;
+ byte_t starting_sector;
+ byte_t starting_cylinder;
+
+ byte_t system_indicator;
+ byte_t ending_head;
+ byte_t ending_sector;
+ byte_t ending_cylinder;
+
+ dword_t beginning_sector;
+ dword_t number_of_sectors;
+} partition_entry_t;
+
+#define BootActive 0x80
+#define SystemPrep 0x41
+
+void copy_image(int , int);
+void write_prep_partition(int , int );
+void write_asm_data( int in, int out );
+
+unsigned int elfhdr_size = 65536;
+
+int main(int argc, char *argv[])
+{
+ int in_fd, out_fd;
+ int argptr = 1;
+ unsigned int prep = 0;
+ unsigned int asmoutput = 0;
+
+ if ( (argc < 3) || (argc > 4) )
+ {
+ fprintf(stderr, "usage: %s [-pbp] [-asm] <boot-file> <image>\n",argv[0]);
+ exit(-1);
+ }
+
+ /* needs to handle args more elegantly -- but this is a small/simple program */
+
+ /* check for -pbp */
+ if ( !strcmp( argv[argptr], "-pbp" ) )
+ {
+ prep = 1;
+ argptr++;
+ }
+
+ /* check for -asm */
+ if ( !strcmp( argv[argptr], "-asm" ) )
+ {
+ asmoutput = 1;
+ argptr++;
+ }
+
+ /* input file */
+ if ( !strcmp( argv[argptr], "-" ) )
+ in_fd = 0; /* stdin */
+ else
+ if ((in_fd = open( argv[argptr] , 0)) < 0)
+ exit(-1);
+ argptr++;
+
+ /* output file */
+ if ( !strcmp( argv[argptr], "-" ) )
+ out_fd = 1; /* stdout */
+ else
+ if ((out_fd = creat( argv[argptr] , 0755)) < 0)
+ exit(-1);
+ argptr++;
+
+ /* skip elf header in input file */
+ /*if ( !prep )*/
+ lseek(in_fd, elfhdr_size, SEEK_SET);
+
+ /* write prep partition if necessary */
+ if ( prep )
+ write_prep_partition( in_fd, out_fd );
+
+ /* write input image to bootimage */
+ if ( asmoutput )
+ write_asm_data( in_fd, out_fd );
+ else
+ copy_image(in_fd, out_fd);
+
+ return 0;
+}
+
+void write_prep_partition(int in, int out)
+{
+ unsigned char block[512];
+ partition_entry_t *pe = (partition_entry_t *)&block[0x1BE];
+ dword_t *entry = (dword_t *)&block[0];
+ dword_t *length = (dword_t *)&block[sizeof(long)];
+ struct stat info;
+
+ if (fstat(in, &info) < 0)
+ {
+ fprintf(stderr,"info failed\n");
+ exit(-1);
+ }
+
+ bzero( block, sizeof block );
+
+ /* set entry point and boot image size skipping over elf header */
+#ifdef __i386__
+ *entry = 0x400/*+65536*/;
+ *length = info.st_size-elfhdr_size+0x400;
+#else
+ *entry = cpu_to_le32(0x400/*+65536*/);
+ *length = cpu_to_le32(info.st_size-elfhdr_size+0x400);
+#endif /* __i386__ */
+
+ /* sets magic number for msdos partition (used by linux) */
+ block[510] = 0x55;
+ block[511] = 0xAA;
+
+ /*
+ * Build a "PReP" partition table entry in the boot record
+ * - "PReP" may only look at the system_indicator
+ */
+ pe->boot_indicator = BootActive;
+ pe->system_indicator = SystemPrep;
+ /*
+ * The first block of the diskette is used by this "boot record" which
+ * actually contains the partition table. (The first block of the
+ * partition contains the boot image, but I digress...) We'll set up
+ * one partition on the diskette and it shall contain the rest of the
+ * diskette.
+ */
+ pe->starting_head = 0; /* zero-based */
+ pe->starting_sector = 2; /* one-based */
+ pe->starting_cylinder = 0; /* zero-based */
+ pe->ending_head = 1; /* assumes two heads */
+ pe->ending_sector = 18; /* assumes 18 sectors/track */
+ pe->ending_cylinder = 79; /* assumes 80 cylinders/diskette */
+
+ /*
+ * The "PReP" software ignores the above fields and just looks at
+ * the next two.
+ * - size of the diskette is (assumed to be)
+ * (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette)
+ * - unlike the above sector numbers, the beginning sector is zero-based!
+ */
+#if 0
+ pe->beginning_sector = cpu_to_le32(1);
+#else
+ /* This has to be 0 on the PowerStack? */
+#ifdef __i386__
+ pe->beginning_sector = 0;
+#else
+ pe->beginning_sector = cpu_to_le32(0);
+#endif /* __i386__ */
+#endif
+
+#ifdef __i386__
+ pe->number_of_sectors = 2*18*80-1;
+#else
+ pe->number_of_sectors = cpu_to_le32(2*18*80-1);
+#endif /* __i386__ */
+
+ write( out, block, sizeof(block) );
+ write( out, entry, sizeof(*entry) );
+ write( out, length, sizeof(*length) );
+ /* set file position to 2nd sector where image will be written */
+ lseek( out, 0x400, SEEK_SET );
+}
+
+
+
+void
+copy_image(int in, int out)
+{
+ char buf[SIZE];
+ int n;
+
+ while ( (n = read(in, buf, SIZE)) > 0 )
+ write(out, buf, n);
+}
+
+
+void
+write_asm_data( int in, int out )
+{
+ int i, cnt, pos, len;
+ unsigned int cksum, val;
+ unsigned char *lp;
+ unsigned char buf[SIZE];
+ unsigned char str[256];
+
+ write( out, "\t.data\n\t.globl input_data\ninput_data:\n",
+ strlen( "\t.data\n\t.globl input_data\ninput_data:\n" ) );
+ pos = 0;
+ cksum = 0;
+ while ((len = read(in, buf, sizeof(buf))) > 0)
+ {
+ cnt = 0;
+ lp = (unsigned char *)buf;
+ len = (len + 3) & ~3; /* Round up to longwords */
+ for (i = 0; i < len; i += 4)
+ {
+ if (cnt == 0)
+ {
+ write( out, "\t.long\t", strlen( "\t.long\t" ) );
+ }
+ sprintf( str, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
+ write( out, str, strlen(str) );
+ val = *(unsigned long *)lp;
+ cksum ^= val;
+ lp += 4;
+ if (++cnt == 4)
+ {
+ cnt = 0;
+ sprintf( str, " # %x \n", pos+i-12);
+ write( out, str, strlen(str) );
+ } else
+ {
+ write( out, ",", 1 );
+ }
+ }
+ if (cnt)
+ {
+ write( out, "0\n", 2 );
+ }
+ pos += len;
+ }
+ sprintf(str, "\t.globl input_len\ninput_len:\t.long\t0x%x\n", pos);
+ write( out, str, strlen(str) );
+
+ fprintf(stderr, "cksum = %x\n", cksum);
+}
--- /dev/null
+/*
+ * BK Id: SCCS/s.mksimage.c 1.6 05/18/01 15:16:42 cort
+ */
+/*
+ *
+ *
+ *
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+
+#define SIZE 1024
+#define BLOCK_ALIGN(x) (((x)+SIZE-1)&(~(SIZE-1)))
+
+static void
+die(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ fputc('\n', stderr);
+ exit(1);
+}
+
+static void
+usage(void)
+{
+ printf("Usage: mkbinimg <bootstrap> <kernel> <ramdisk> -o <binary>\n");
+ exit(1);
+}
+
+static int
+copy_blocks(int ifd, int ofd, unsigned long *offset, unsigned long *size)
+{
+ off_t cur;
+ int amt;
+ unsigned long len = 0;
+ char buffer[SIZE];
+
+ cur = lseek(ofd, 0, SEEK_CUR);
+
+ if (cur % SIZE) {
+ cur = BLOCK_ALIGN(cur);
+ cur = lseek(ofd, cur, SEEK_SET);
+ }
+
+ *offset = (unsigned long) cur;
+ while((amt = read(ifd, buffer, SIZE)) > 0) {
+ write(ofd, buffer, amt);
+ len += amt;
+ }
+ *size = len;
+ return 0;
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ char *kernel, *loader, *rdimage = NULL;
+ unsigned long ld_off, kern_off, rd_off;
+ unsigned long ld_size, kern_size, rd_size;
+ int fd, ofd, len;
+ char buffer[500];
+
+ if (argc < 5 && !strcmp(argv[argc-2], "-o"))
+ usage();
+
+ if (argc > 5)
+ rdimage = argv[3];
+
+ kernel = argv[2];
+ loader = argv[1];
+
+ ofd = open(argv[argc-1], (O_RDWR|O_CREAT), 0755);
+ if (ofd < 0) {
+ die("can't open %s: %s", argv[5], strerror(errno));
+ }
+
+ ld_off = kern_off = rd_off = 0;
+ ld_size = kern_size = rd_size = 0;
+ memset(buffer, 0, 500);
+ len = 0;
+
+ fd = open(loader, O_RDONLY);
+ if (fd < 0)
+ die("can't open loader: %s", strerror(errno));
+
+ copy_blocks(fd, ofd, &ld_off, &ld_size);
+ len = sprintf(buffer, "bootloader: %x %x\n", ld_off, ld_size);
+ close(fd);
+
+ fd = open(kernel, O_RDONLY);
+ if (fd < 0)
+ die("can't open kernel: %s", strerror(errno));
+
+ copy_blocks(fd, ofd, &kern_off, &kern_size);
+ len += sprintf(buffer+len, "zimage: %x %x\n", kern_off, kern_size);
+ close(fd);
+
+ if (rdimage) {
+ fd = open(rdimage, O_RDONLY);
+ if (fd < 0)
+ die("can't get ramdisk: %s", strerror(errno));
+
+ copy_blocks(fd, ofd, &rd_off, &rd_size);
+ close(fd);
+ }
+
+ len += sprintf(buffer+len, "initrd: %x %x", rd_off, rd_size);
+
+ close(ofd);
+
+ printf("%s\n", buffer);
+
+ return 0;
+}
+
--- /dev/null
+#!/bin/bash
+
+OFFSET=`$1 -h $2 | grep $3 | grep -v zvmlinux| awk '{print $6}'`
+echo "0x"$OFFSET
--- /dev/null
+/*
+ * BK Id: SCCS/s.piggyback.c 1.7 05/18/01 15:17:23 cort
+ */
+#include <stdio.h>
+#include <unistd.h>
+
+extern long ce_exec_config[];
+
+int main(int argc, char *argv[])
+{
+ int i, cnt, pos, len;
+ unsigned int cksum, val;
+ unsigned char *lp;
+ unsigned char buf[8192];
+ if (argc != 2)
+ {
+ fprintf(stderr, "usage: %s name <in-file >out-file\n",
+ argv[0]);
+ exit(1);
+ }
+ fprintf(stdout, "#\n");
+ fprintf(stdout, "# Miscellaneous data structures:\n");
+ fprintf(stdout, "# WARNING - this file is automatically generated!\n");
+ fprintf(stdout, "#\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "\t.data\n");
+ fprintf(stdout, "\t.globl %s_data\n", argv[1]);
+ fprintf(stdout, "%s_data:\n", argv[1]);
+ pos = 0;
+ cksum = 0;
+ while ((len = read(0, buf, sizeof(buf))) > 0)
+ {
+ cnt = 0;
+ lp = (unsigned char *)buf;
+ len = (len + 3) & ~3; /* Round up to longwords */
+ for (i = 0; i < len; i += 4)
+ {
+ if (cnt == 0)
+ {
+ fprintf(stdout, "\t.long\t");
+ }
+ fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
+ val = *(unsigned long *)lp;
+ cksum ^= val;
+ lp += 4;
+ if (++cnt == 4)
+ {
+ cnt = 0;
+ fprintf(stdout, " # %x \n", pos+i-12);
+ fflush(stdout);
+ } else
+ {
+ fprintf(stdout, ",");
+ }
+ }
+ if (cnt)
+ {
+ fprintf(stdout, "0\n");
+ }
+ pos += len;
+ }
+ fprintf(stdout, "\t.globl %s_len\n", argv[1]);
+ fprintf(stdout, "%s_len:\t.long\t0x%x\n", argv[1], pos);
+ fflush(stdout);
+ fclose(stdout);
+ fprintf(stderr, "cksum = %x\n", cksum);
+ exit(0);
+}
+
--- /dev/null
+#!/bin/bash
+
+OFFSET=`grep $1 sImage.map | awk '{print $2}'`
+echo "0x"$OFFSET
--- /dev/null
+#!/bin/bash
+
+OFFSET=`grep $1 sImage.map | awk '{print $3}'`
+echo "0x"$OFFSET
--- /dev/null
+#!/bin/bash
+
+OFFSET=`$1 -h $2 | grep $3 | grep -v zvmlinux | awk '{print $3}'`
+echo "0x"$OFFSET
+++ /dev/null
-/*
- * vreset.c
- *
- * Initialize the VGA control registers to 80x25 text mode.
- *
- * Adapted from a program by:
- * Steve Sellgren
- * San Francisco Indigo Company
- * sfindigo!sellgren@uunet.uu.net
- *
- * Original concept by:
- * Gary Thomas <gdt@linuxppc.org>
- * Adapted for Moto boxes by:
- * Pat Kane & Mark Scott, 1996
- * Adapted for IBM portables by:
- * Takeshi Ishimoto
- * Multi-console support:
- * Terje Malmedal <terje.malmedal@usit.uio.no>
- */
-
-#include "iso_font.h"
-
-extern char *vidmem;
-extern int lines, cols;
-
-static void mdelay(int ms)
-{
- for (; ms > 0; --ms)
- udelay(1000);
-}
-
-/*
- * VGA Register
- */
-struct VgaRegs
-{
- unsigned short io_port;
- unsigned char io_index;
- unsigned char io_value;
-};
-
-/*
- * Default console text mode registers used to reset
- * graphics adapter.
- */
-#define NREGS 54
-#define ENDMK 0xFFFF /* End marker */
-
-#define S3Vendor 0x5333
-#define CirrusVendor 0x1013
-#define DiamondVendor 0x100E
-#define MatroxVendor 0x102B
-#define ParadiseVendor 0x101C
-
-struct VgaRegs GenVgaTextRegs[NREGS+1] = {
-/* port index value */
- /* SR Regs */
- 0x3c4, 0x1, 0x0,
- 0x3c4, 0x2, 0x3,
- 0x3c4, 0x3, 0x0,
- 0x3c4, 0x4, 0x2,
- /* CR Regs */
- 0x3d4, 0x0, 0x5f,
- 0x3d4, 0x1, 0x4f,
- 0x3d4, 0x2, 0x50,
- 0x3d4, 0x3, 0x82,
- 0x3d4, 0x4, 0x55,
- 0x3d4, 0x5, 0x81,
- 0x3d4, 0x6, 0xbf,
- 0x3d4, 0x7, 0x1f,
- 0x3d4, 0x8, 0x00,
- 0x3d4, 0x9, 0x4f,
- 0x3d4, 0xa, 0x0d,
- 0x3d4, 0xb, 0x0e,
- 0x3d4, 0xc, 0x00,
- 0x3d4, 0xd, 0x00,
- 0x3d4, 0xe, 0x00,
- 0x3d4, 0xf, 0x00,
- 0x3d4, 0x10, 0x9c,
- 0x3d4, 0x11, 0x8e,
- 0x3d4, 0x12, 0x8f,
- 0x3d4, 0x13, 0x28,
- 0x3d4, 0x14, 0x1f,
- 0x3d4, 0x15, 0x96,
- 0x3d4, 0x16, 0xb9,
- 0x3d4, 0x17, 0xa3,
- /* GR Regs */
- 0x3ce, 0x0, 0x0,
- 0x3ce, 0x1, 0x0,
- 0x3ce, 0x2, 0x0,
- 0x3ce, 0x3, 0x0,
- 0x3ce, 0x4, 0x0,
- 0x3ce, 0x5, 0x10,
- 0x3ce, 0x6, 0xe,
- 0x3ce, 0x7, 0x0,
- 0x3ce, 0x8, 0xff,
- ENDMK
-};
-
-struct VgaRegs S3TextRegs[NREGS+1] = {
-/* port index value */
- /* SR Regs */
- 0x3c4, 0x1, 0x0,
- 0x3c4, 0x2, 0x3,
- 0x3c4, 0x3, 0x0,
- 0x3c4, 0x4, 0x2,
- /* CR Regs */
- 0x3d4, 0x0, 0x5f,
- 0x3d4, 0x1, 0x4f,
- 0x3d4, 0x2, 0x50,
- 0x3d4, 0x3, 0x82,
- 0x3d4, 0x4, 0x55,
- 0x3d4, 0x5, 0x81,
- 0x3d4, 0x6, 0xbf,
- 0x3d4, 0x7, 0x1f,
- 0x3d4, 0x8, 0x00,
- 0x3d4, 0x9, 0x4f,
- 0x3d4, 0xa, 0x0d,
- 0x3d4, 0xb, 0x0e,
- 0x3d4, 0xc, 0x00,
- 0x3d4, 0xd, 0x00,
- 0x3d4, 0xe, 0x00,
- 0x3d4, 0xf, 0x00,
- 0x3d4, 0x10, 0x9c,
- 0x3d4, 0x11, 0x8e,
- 0x3d4, 0x12, 0x8f,
- 0x3d4, 0x13, 0x28,
- 0x3d4, 0x14, 0x1f,
- 0x3d4, 0x15, 0x96,
- 0x3d4, 0x16, 0xb9,
- 0x3d4, 0x17, 0xa3,
- /* GR Regs */
- 0x3ce, 0x0, 0x0,
- 0x3ce, 0x1, 0x0,
- 0x3ce, 0x2, 0x0,
- 0x3ce, 0x3, 0x0,
- 0x3ce, 0x4, 0x0,
- 0x3ce, 0x5, 0x10,
- 0x3ce, 0x6, 0xe,
- 0x3ce, 0x7, 0x0,
- 0x3ce, 0x8, 0xff,
- ENDMK
-};
-
-struct RGBColors
-{
- unsigned char r, g, b;
-};
-
-/*
- * Default console text mode color table.
- * These values were obtained by booting Linux with
- * text mode firmware & then dumping the registers.
- */
-struct RGBColors TextCLUT[256] =
-{
- /* red green blue */
- 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x2a,
- 0x0, 0x2a, 0x0,
- 0x0, 0x2a, 0x2a,
- 0x2a, 0x0, 0x0,
- 0x2a, 0x0, 0x2a,
- 0x2a, 0x2a, 0x0,
- 0x2a, 0x2a, 0x2a,
- 0x0, 0x0, 0x15,
- 0x0, 0x0, 0x3f,
- 0x0, 0x2a, 0x15,
- 0x0, 0x2a, 0x3f,
- 0x2a, 0x0, 0x15,
- 0x2a, 0x0, 0x3f,
- 0x2a, 0x2a, 0x15,
- 0x2a, 0x2a, 0x3f,
- 0x0, 0x15, 0x0,
- 0x0, 0x15, 0x2a,
- 0x0, 0x3f, 0x0,
- 0x0, 0x3f, 0x2a,
- 0x2a, 0x15, 0x0,
- 0x2a, 0x15, 0x2a,
- 0x2a, 0x3f, 0x0,
- 0x2a, 0x3f, 0x2a,
- 0x0, 0x15, 0x15,
- 0x0, 0x15, 0x3f,
- 0x0, 0x3f, 0x15,
- 0x0, 0x3f, 0x3f,
- 0x2a, 0x15, 0x15,
- 0x2a, 0x15, 0x3f,
- 0x2a, 0x3f, 0x15,
- 0x2a, 0x3f, 0x3f,
- 0x15, 0x0, 0x0,
- 0x15, 0x0, 0x2a,
- 0x15, 0x2a, 0x0,
- 0x15, 0x2a, 0x2a,
- 0x3f, 0x0, 0x0,
- 0x3f, 0x0, 0x2a,
- 0x3f, 0x2a, 0x0,
- 0x3f, 0x2a, 0x2a,
- 0x15, 0x0, 0x15,
- 0x15, 0x0, 0x3f,
- 0x15, 0x2a, 0x15,
- 0x15, 0x2a, 0x3f,
- 0x3f, 0x0, 0x15,
- 0x3f, 0x0, 0x3f,
- 0x3f, 0x2a, 0x15,
- 0x3f, 0x2a, 0x3f,
- 0x15, 0x15, 0x0,
- 0x15, 0x15, 0x2a,
- 0x15, 0x3f, 0x0,
- 0x15, 0x3f, 0x2a,
- 0x3f, 0x15, 0x0,
- 0x3f, 0x15, 0x2a,
- 0x3f, 0x3f, 0x0,
- 0x3f, 0x3f, 0x2a,
- 0x15, 0x15, 0x15,
- 0x15, 0x15, 0x3f,
- 0x15, 0x3f, 0x15,
- 0x15, 0x3f, 0x3f,
- 0x3f, 0x15, 0x15,
- 0x3f, 0x15, 0x3f,
- 0x3f, 0x3f, 0x15,
- 0x3f, 0x3f, 0x3f,
- 0x39, 0xc, 0x5,
- 0x15, 0x2c, 0xf,
- 0x26, 0x10, 0x3d,
- 0x29, 0x29, 0x38,
- 0x4, 0x1a, 0xe,
- 0x2, 0x1e, 0x3a,
- 0x3c, 0x25, 0x33,
- 0x3c, 0xc, 0x2c,
- 0x3f, 0x3, 0x2b,
- 0x1c, 0x9, 0x13,
- 0x25, 0x2a, 0x35,
- 0x1e, 0xa, 0x38,
- 0x24, 0x8, 0x3,
- 0x3, 0xe, 0x36,
- 0xc, 0x6, 0x2a,
- 0x26, 0x3, 0x32,
- 0x5, 0x2f, 0x33,
- 0x3c, 0x35, 0x2f,
- 0x2d, 0x26, 0x3e,
- 0xd, 0xa, 0x10,
- 0x25, 0x3c, 0x11,
- 0xd, 0x4, 0x2e,
- 0x5, 0x19, 0x3e,
- 0xc, 0x13, 0x34,
- 0x2b, 0x6, 0x24,
- 0x4, 0x3, 0xd,
- 0x2f, 0x3c, 0xc,
- 0x2a, 0x37, 0x1f,
- 0xf, 0x12, 0x38,
- 0x38, 0xe, 0x2a,
- 0x12, 0x2f, 0x19,
- 0x29, 0x2e, 0x31,
- 0x25, 0x13, 0x3e,
- 0x33, 0x3e, 0x33,
- 0x1d, 0x2c, 0x25,
- 0x15, 0x15, 0x5,
- 0x32, 0x25, 0x39,
- 0x1a, 0x7, 0x1f,
- 0x13, 0xe, 0x1d,
- 0x36, 0x17, 0x34,
- 0xf, 0x15, 0x23,
- 0x2, 0x35, 0xd,
- 0x15, 0x3f, 0xc,
- 0x14, 0x2f, 0xf,
- 0x19, 0x21, 0x3e,
- 0x27, 0x11, 0x2f,
- 0x38, 0x3f, 0x3c,
- 0x36, 0x2d, 0x15,
- 0x16, 0x17, 0x2,
- 0x1, 0xa, 0x3d,
- 0x1b, 0x11, 0x3f,
- 0x21, 0x3c, 0xd,
- 0x1a, 0x39, 0x3d,
- 0x8, 0xe, 0xe,
- 0x22, 0x21, 0x23,
- 0x1e, 0x30, 0x5,
- 0x1f, 0x22, 0x3d,
- 0x1e, 0x2f, 0xa,
- 0x0, 0x1c, 0xe,
- 0x0, 0x1c, 0x15,
- 0x0, 0x1c, 0x1c,
- 0x0, 0x15, 0x1c,
- 0x0, 0xe, 0x1c,
- 0x0, 0x7, 0x1c,
- 0xe, 0xe, 0x1c,
- 0x11, 0xe, 0x1c,
- 0x15, 0xe, 0x1c,
- 0x18, 0xe, 0x1c,
- 0x1c, 0xe, 0x1c,
- 0x1c, 0xe, 0x18,
- 0x1c, 0xe, 0x15,
- 0x1c, 0xe, 0x11,
- 0x1c, 0xe, 0xe,
- 0x1c, 0x11, 0xe,
- 0x1c, 0x15, 0xe,
- 0x1c, 0x18, 0xe,
- 0x1c, 0x1c, 0xe,
- 0x18, 0x1c, 0xe,
- 0x15, 0x1c, 0xe,
- 0x11, 0x1c, 0xe,
- 0xe, 0x1c, 0xe,
- 0xe, 0x1c, 0x11,
- 0xe, 0x1c, 0x15,
- 0xe, 0x1c, 0x18,
- 0xe, 0x1c, 0x1c,
- 0xe, 0x18, 0x1c,
- 0xe, 0x15, 0x1c,
- 0xe, 0x11, 0x1c,
- 0x14, 0x14, 0x1c,
- 0x16, 0x14, 0x1c,
- 0x18, 0x14, 0x1c,
- 0x1a, 0x14, 0x1c,
- 0x1c, 0x14, 0x1c,
- 0x1c, 0x14, 0x1a,
- 0x1c, 0x14, 0x18,
- 0x1c, 0x14, 0x16,
- 0x1c, 0x14, 0x14,
- 0x1c, 0x16, 0x14,
- 0x1c, 0x18, 0x14,
- 0x1c, 0x1a, 0x14,
- 0x1c, 0x1c, 0x14,
- 0x1a, 0x1c, 0x14,
- 0x18, 0x1c, 0x14,
- 0x16, 0x1c, 0x14,
- 0x14, 0x1c, 0x14,
- 0x14, 0x1c, 0x16,
- 0x14, 0x1c, 0x18,
- 0x14, 0x1c, 0x1a,
- 0x14, 0x1c, 0x1c,
- 0x14, 0x1a, 0x1c,
- 0x14, 0x18, 0x1c,
- 0x14, 0x16, 0x1c,
- 0x0, 0x0, 0x10,
- 0x4, 0x0, 0x10,
- 0x8, 0x0, 0x10,
- 0xc, 0x0, 0x10,
- 0x10, 0x0, 0x10,
- 0x10, 0x0, 0xc,
- 0x10, 0x0, 0x8,
- 0x10, 0x0, 0x4,
- 0x10, 0x0, 0x0,
- 0x10, 0x4, 0x0,
- 0x10, 0x8, 0x0,
- 0x10, 0xc, 0x0,
- 0x10, 0x10, 0x0,
- 0xc, 0x10, 0x0,
- 0x8, 0x10, 0x0,
- 0x4, 0x10, 0x0,
- 0x0, 0x10, 0x0,
- 0x0, 0x10, 0x4,
- 0x0, 0x10, 0x8,
- 0x0, 0x10, 0xc,
- 0x0, 0x10, 0x10,
- 0x0, 0xc, 0x10,
- 0x0, 0x8, 0x10,
- 0x0, 0x4, 0x10,
- 0x8, 0x8, 0x10,
- 0xa, 0x8, 0x10,
- 0xc, 0x8, 0x10,
- 0xe, 0x8, 0x10,
- 0x10, 0x8, 0x10,
- 0x10, 0x8, 0xe,
- 0x10, 0x8, 0xc,
- 0x10, 0x8, 0xa,
- 0x10, 0x8, 0x8,
- 0x10, 0xa, 0x8,
- 0x10, 0xc, 0x8,
- 0x10, 0xe, 0x8,
- 0x10, 0x10, 0x8,
- 0xe, 0x10, 0x8,
- 0xc, 0x10, 0x8,
- 0xa, 0x10, 0x8,
- 0x8, 0x10, 0x8,
- 0x8, 0x10, 0xa,
- 0x8, 0x10, 0xc,
- 0x8, 0x10, 0xe,
- 0x8, 0x10, 0x10,
- 0x8, 0xe, 0x10,
- 0x8, 0xc, 0x10,
- 0x8, 0xa, 0x10,
- 0xb, 0xb, 0x10,
- 0xc, 0xb, 0x10,
- 0xd, 0xb, 0x10,
- 0xf, 0xb, 0x10,
- 0x10, 0xb, 0x10,
- 0x10, 0xb, 0xf,
- 0x10, 0xb, 0xd,
- 0x10, 0xb, 0xc,
- 0x10, 0xb, 0xb,
- 0x10, 0xc, 0xb,
- 0x10, 0xd, 0xb,
- 0x10, 0xf, 0xb,
- 0x10, 0x10, 0xb,
- 0xf, 0x10, 0xb,
- 0xd, 0x10, 0xb,
- 0xc, 0x10, 0xb,
- 0xb, 0x10, 0xb,
- 0xb, 0x10, 0xc,
- 0xb, 0x10, 0xd,
- 0xb, 0x10, 0xf,
- 0xb, 0x10, 0x10,
- 0xb, 0xf, 0x10,
- 0xb, 0xd, 0x10,
- 0xb, 0xc, 0x10,
- 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0
-};
-
-unsigned char AC[21] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
- 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
- 0x0C, 0x00, 0x0F, 0x08, 0x00};
-
-static int scanPCI(int start_slt);
-static int PCIVendor(int);
-static void printslots(void);
-extern void puthex(unsigned long);
-extern void puts(const char *);
-static void unlockS3(void);
-
-static inline
-outw(int port, unsigned short val)
-{
- outb(port, val >> 8);
- outb(port+1, val);
-}
-
-#define PPC_601 1
-
-vga_init(unsigned char *ISA_mem)
-{
- int slot;
- struct VgaRegs *VgaTextRegs;
-#if 0
- if ((_get_PVR()>>16) == PPC_601) {
- return(old_vga_init(ISA_mem));
- }
-#endif
-
- /* See if VGA already in TEXT mode - exit if so! */
- outb(0x3CE, 0x06);
- if ((inb(0x3CF) & 0x01) == 0){puts("VGA already in text mode\n"); return;}
-
- /* If no VGA responding in text mode, then we have some work to do...
- */
- slot = -1;
- while((slot = scanPCI(slot)) > -1) { /* find video card in use */
- unlockVideo(slot); /* enable I/O to card */
- VgaTextRegs = GenVgaTextRegs;
-
- switch (PCIVendor(slot)) {
- default:
- break;
- case(S3Vendor):
- unlockS3();
- VgaTextRegs = S3TextRegs;
- break;
-
- case(CirrusVendor):
- outw(0x3C4, 0x0612); /* unlock ext regs */
- outw(0x3C4, 0x0700); /* reset ext sequence mode */
- break;
-
- case(ParadiseVendor): /* IBM Portable 850 */
- outw(0x3ce, 0x0f05); /* unlock pardise registers */
- outw(0x3c4, 0x0648);
- outw(0x3d4, 0x2985);
- outw(0x3d4, 0x34a6);
- outb(0x3ce, 0x0b); /* disable linear addressing */
- outb(0x3cf, inb(0x3cf) & ~0x30);
- outw(0x3c4, 0x1400);
- outb(0x3ce, 0x0e); /* disable 256 color mode */
- outb(0x3cf, inb(0x3cf) & ~0x01);
- outb(0xd00, 0xff); /* enable auto-centering */
- if (!(inb(0xd01) & 0x03)) {
- outb(0x3d4, 0x33);
- outb(0x3d5, inb(0x3d5) & ~0x90);
- outb(0x3d4, 0x32);
- outb(0x3d5, inb(0x3d5) | 0x04);
- outw(0x3d4, 0x0250);
- outw(0x3d4, 0x07ba);
- outw(0x3d4, 0x0900);
- outw(0x3d4, 0x15e7);
- outw(0x3d4, 0x2a95);
- }
- outw(0x3d4, 0x34a0);
- break;
-
- #if 0 /* Untested - probably doesn't work */
- case(MatroxVendor):
- case(DiamondVendor):
- puts("VGA Chip Vendor ID: ");
- puthex(PCIVendor(slot));
- puts("\n");
- mdelay(1000);
- #endif
- };
-
- outw(0x3C4, 0x0120); /* disable video */
- setTextRegs(VgaTextRegs); /* initial register setup */
- setTextCLUT(0); /* load color lookup table */
- loadFont(ISA_mem); /* load font */
- setTextRegs(VgaTextRegs); /* reload registers */
- outw(0x3C4, 0x0100); /* re-enable video */
- clearVideoMemory();
-
- if (PCIVendor(slot) == S3Vendor) {
- outb(0x3c2, 0x63); /* MISC */
- } /* endif */
-
- #ifdef DEBUG
- printslots();
- mdelay(5000);
- #endif
-
- mdelay(1000); /* give time for the video monitor to come up */
- }
- return (1); /* 'CRT' I/O supported */
-}
-
-/*
- * Write to VGA Attribute registers.
- */
-writeAttr(index, data, videoOn)
- unsigned char index;
- unsigned char data;
- unsigned char videoOn; /* video on flag */
-{
- unsigned char v;
- v = inb(0x3da); /* reset attr. address toggle */
- if (videoOn)
- outb(0x3c0, (index & 0x1F) | 0x20);
- else
- outb(0x3c0, (index & 0x1F));
- outb(0x3c0, data);
-}
-
-setTextRegs(struct VgaRegs *svp)
-{
- int i;
-
- /*
- * saved settings
- */
- while( svp->io_port != ENDMK ) {
- outb(svp->io_port, svp->io_index);
- outb(svp->io_port+1, svp->io_value);
- svp++;
- }
-
- outb(0x3c2, 0x67); /* MISC */
- outb(0x3c6, 0xff); /* MASK */
-
- for ( i = 0; i < 0x10; i++)
- writeAttr(i, AC[i], 0); /* pallete */
- writeAttr(0x10, 0x0c, 0); /* text mode */
- writeAttr(0x11, 0x00, 0); /* overscan color (border) */
- writeAttr(0x12, 0x0f, 0); /* plane enable */
- writeAttr(0x13, 0x08, 0); /* pixel panning */
- writeAttr(0x14, 0x00, 1); /* color select; video on */
-}
-
-setTextCLUT(int shift)
-{
- int i;
-
- outb(0x3C6, 0xFF);
- i = inb(0x3C7);
- outb(0x3C8, 0);
- i = inb(0x3C7);
-
- for ( i = 0; i < 256; i++) {
- outb(0x3C9, TextCLUT[i].r << shift);
- outb(0x3C9, TextCLUT[i].g << shift);
- outb(0x3C9, TextCLUT[i].b << shift);
- }
-}
-
-
-loadFont(unsigned char *ISA_mem)
-{
- int i, j;
- unsigned char *font_page = (unsigned char *) &ISA_mem[0xA0000];
-
- outb(0x3C2, 0x67);
- /*
- * Load font
- */
- i = inb(0x3DA); /* Reset Attr toggle */
-
- outb(0x3C0,0x30);
- outb(0x3C0, 0x01); /* graphics mode */
-
- outw(0x3C4, 0x0001); /* reset sequencer */
- outw(0x3C4, 0x0204); /* write to plane 2 */
- outw(0x3C4, 0x0406); /* enable plane graphics */
- outw(0x3C4, 0x0003); /* reset sequencer */
- outw(0x3CE, 0x0402); /* read plane 2 */
- outw(0x3CE, 0x0500); /* write mode 0, read mode 0 */
- outw(0x3CE, 0x0605); /* set graphics mode */
-
- for (i = 0; i < sizeof(font); i += 16) {
- for (j = 0; j < 16; j++) {
- __asm__ volatile("eieio");
- font_page[(2*i)+j] = font[i+j];
- }
- }
-}
-
-static void
-unlockS3(void)
-{
- int s3_device_id;
- outw(0x3d4, 0x3848);
- outw(0x3d4, 0x39a5);
- outb(0x3d4, 0x2d);
- s3_device_id = inb(0x3d5) << 8;
- outb(0x3d4, 0x2e);
- s3_device_id |= inb(0x3d5);
-
- if (s3_device_id != 0x8812) {
- /* From the S3 manual */
- outb(0x46E8, 0x10); /* Put into setup mode */
- outb(0x3C3, 0x10);
- outb(0x102, 0x01); /* Enable registers */
- outb(0x46E8, 0x08); /* Enable video */
- outb(0x3C3, 0x08);
- outb(0x4AE8, 0x00);
-
-#if 0
- outb(0x42E8, 0x80); /* Reset graphics engine? */
-#endif
-
- outb(0x3D4, 0x38); /* Unlock all registers */
- outb(0x3D5, 0x48);
- outb(0x3D4, 0x39);
- outb(0x3D5, 0xA5);
- outb(0x3D4, 0x40);
- outb(0x3D5, inb(0x3D5)|0x01);
- outb(0x3D4, 0x33);
- outb(0x3D5, inb(0x3D5)&~0x52);
- outb(0x3D4, 0x35);
- outb(0x3D5, inb(0x3D5)&~0x30);
- outb(0x3D4, 0x3A);
- outb(0x3D5, 0x00);
- outb(0x3D4, 0x53);
- outb(0x3D5, 0x00);
- outb(0x3D4, 0x31);
- outb(0x3D5, inb(0x3D5)&~0x4B);
- outb(0x3D4, 0x58);
-
- outb(0x3D5, 0);
-
- outb(0x3D4, 0x54);
- outb(0x3D5, 0x38);
- outb(0x3D4, 0x60);
- outb(0x3D5, 0x07);
- outb(0x3D4, 0x61);
- outb(0x3D5, 0x80);
- outb(0x3D4, 0x62);
- outb(0x3D5, 0xA1);
- outb(0x3D4, 0x69); /* High order bits for cursor address */
- outb(0x3D5, 0);
-
- outb(0x3D4, 0x32);
- outb(0x3D5, inb(0x3D5)&~0x10);
- } else {
- outw(0x3c4, 0x0806); /* IBM Portable 860 */
- outw(0x3c4, 0x1041);
- outw(0x3c4, 0x1128);
- outw(0x3d4, 0x4000);
- outw(0x3d4, 0x3100);
- outw(0x3d4, 0x3a05);
- outw(0x3d4, 0x6688);
- outw(0x3d4, 0x5800); /* disable linear addressing */
- outw(0x3d4, 0x4500); /* disable H/W cursor */
- outw(0x3c4, 0x5410); /* enable auto-centering */
- outw(0x3c4, 0x561f);
- outw(0x3c4, 0x1b80); /* lock DCLK selection */
- outw(0x3d4, 0x3900); /* lock S3 registers */
- outw(0x3d4, 0x3800);
- } /* endif */
-}
-
-/*
- * cursor() sets an offset (0-1999) into the 80x25 text area
- */
-void
-cursor(int x, int y)
-{
- int pos = (y*cols)+x;
- outb(0x3D4, 14);
- outb(0x3D5, pos >> 8);
- outb(0x3D4, 15);
- outb(0x3D5, pos);
-}
-
-clearVideoMemory()
-{
- int i, j;
- for (i = 0; i < lines; i++) {
- for (j = 0; j < cols; j++) {
- vidmem[((i*cols)+j)*2] = 0x20; /* fill with space character */
- vidmem[((i*cols)+j)*2+1] = 0x07; /* set bg & fg attributes */
- }
- }
-}
-
-/* ============ */
-
-
-#define NSLOTS 8
-#define NPCIREGS 5
-
-
-/*
- should use devfunc number/indirect method to be totally safe on
- all machines, this works for now on 3 slot Moto boxes
-*/
-
-struct PCI_ConfigInfo {
- unsigned long * config_addr;
- unsigned long regs[NPCIREGS];
-} PCI_slots [NSLOTS] = {
-
- { (unsigned long *)0x80808000, 0xDEADBEEF }, /* onboard */
- { (unsigned long *)0x80800800, 0xDEADBEEF }, /* onboard */
- { (unsigned long *)0x80801000, 0xDEADBEEF }, /* onboard */
- { (unsigned long *)0x80802000, 0xDEADBEEF }, /* onboard */
- { (unsigned long *)0x80804000, 0xDEADBEEF }, /* onboard */
- { (unsigned long *)0x80810000, 0xDEADBEEF }, /* slot A/1 */
- { (unsigned long *)0x80820000, 0xDEADBEEF }, /* slot B/2 */
- { (unsigned long *)0x80840000, 0xDEADBEEF } /* slot C/3 */
-};
-
-
-
-/*
- * The following code modifies the PCI Command register
- * to enable memory and I/O accesses.
- */
-unlockVideo(slot)
-{
- volatile unsigned char * ppci;
-
- ppci = (unsigned char * )PCI_slots[slot].config_addr;
- ppci[4] = 0x0003; /* enable memory and I/O accesses */
- ppci[0x10] = 0x00000; /* turn off memory mapping */
- ppci[0x11] = 0x00000; /* mem_base = 0 */
- ppci[0x12] = 0x00000;
- ppci[0x13] = 0x00000;
- __asm__ volatile("eieio");
-
- outb(0x3d4, 0x11);
- outb(0x3d5, 0x0e); /* unlock CR0-CR7 */
-}
-
-long
-SwapBytes(long lv) /* turn little endian into big indian long */
-{
- long t;
- t = (lv&0x000000FF) << 24;
- t |= (lv&0x0000FF00) << 8;
- t |= (lv&0x00FF0000) >> 8;
- t |= (lv&0xFF000000) >> 24;
- return(t);
-}
-
-
-#define DEVID 0
-#define CMD 1
-#define CLASS 2
-#define MEMBASE 4
-
-int
-scanPCI(int start_slt)
-{
- int slt, r;
- struct PCI_ConfigInfo *pslot;
- int theSlot = -1;
- int highVgaSlot = 0;
-
- for ( slt = start_slt + 1; slt < NSLOTS; slt++) {
- pslot = &PCI_slots[slt];
- for ( r = 0; r < NPCIREGS; r++) {
- pslot->regs[r] = SwapBytes ( pslot->config_addr[r] );
- }
- /* card in slot ? */
- if ( pslot->regs[DEVID] != 0xFFFFFFFF ) {
- /* VGA ? */
- if ( ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x03000000) ||
- ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x00010000)) {
- highVgaSlot = slt;
- /* did firmware enable it ? */
- if ( (pslot->regs[CMD] & 0x03) ) {
- theSlot = slt;
- break;
- }
- }
- }
- }
-
- return ( theSlot );
-}
-
-/* return Vendor ID of card in the slot */
-static
-int PCIVendor(int slotnum) {
- struct PCI_ConfigInfo *pslot;
-
- pslot = &PCI_slots[slotnum];
-
-return (pslot->regs[DEVID] & 0xFFFF);
-}
-
-static
-void printslots(void)
-{
- int i;
- struct PCI_ConfigInfo *pslot;
- for(i=0; i < NSLOTS; i++) {
-#if 0
- pslot = &PCI_slots[i];
- printf("Slot: %d, Addr: %x, Vendor: %08x, Class: %08x\n",
- i, pslot->config_addr, pslot->regs[0], pslot->regs[2]);
-#else
- puts("PCI Slot number: "); puthex(i);
- puts(" Vendor ID: ");
- puthex(PCIVendor(i)); puts("\n");
-#endif
- }
-}
+++ /dev/null
-# Makefile for making ELF bootable images for booting on CHRP
-# using Open Firmware.
-#
-# Geert Uytterhoeven September 1997
-#
-# Based on coffboot by Paul Mackerras
-
-ifeq ($(CONFIG_PPC64BRIDGE),y)
-MSIZE=.64
-AFLAGS += -Wa,-mppc64bridge
-else
-MSIZE=
-endif
-
-.c.o:
- $(CC) $(CFLAGS) -DKERNELBASE=$(KERNELBASE) -c -o $*.o $<
-.S.o:
- $(CC) $(AFLAGS) -traditional -c -o $*.o $<
-
-CFLAGS = $(CPPFLAGS) -O -fno-builtin -DSTDC_HEADERS
-LD_ARGS = -Ttext 0x00400000
-
-OBJS = crt0.o start.o main.o misc.o ../coffboot/string.o ../coffboot/zlib.o image.o
-LIBS = $(TOPDIR)/lib/lib.a
-
-ifeq ($(CONFIG_SMP),y)
-TFTPIMAGE=/tftpboot/zImage.chrp.smp$(MSIZE)
-else
-TFTPIMAGE=/tftpboot/zImage.chrp$(MSIZE)
-endif
-
-all: $(TOPDIR)/zImage
-
-#
-# Only build anything here if we're configured for ALL_PPC
-# -- cort
-#
-ifeq ($(CONFIG_ALL_PPC),y)
-znetboot: zImage
- cp zImage $(TFTPIMAGE)
-
-znetboot.initrd: zImage.initrd
- cp zImage.initrd $(TFTPIMAGE)
-
-floppy: zImage
- mcopy zImage a:zImage
-
-piggyback: piggyback.c
- $(HOSTCC) $(HOSTCFLAGS) -DKERNELBASE=$(KERNELBASE) -o piggyback piggyback.c
-
-addnote: addnote.c
- $(HOSTCC) $(HOSTCFLAGS) -o addnote addnote.c
-
-image.o: piggyback ../coffboot/vmlinux.gz
- ./piggyback image < ../coffboot/vmlinux.gz | $(AS) -o image.o
-
-sysmap.o: piggyback ../../../System.map
- ./piggyback sysmap < ../../../System.map | $(AS) -o sysmap.o
-
-initrd.o: ramdisk.image.gz piggyback
- ./piggyback initrd < ramdisk.image.gz | $(AS) -o initrd.o
-
-zImage: $(OBJS) no_initrd.o addnote
- $(LD) $(LD_ARGS) -o $@ $(OBJS) no_initrd.o $(LIBS)
- cp $@ $@.rs6k
- ./addnote $@.rs6k
-
-zImage.initrd: $(OBJS) initrd.o addnote
- $(LD) $(LD_ARGS) -o $@ $(OBJS) initrd.o $(LIBS)
- cp $@ $@.rs6k
- ./addnote $@.rs6k
-
-else
-znetboot:
-
-znetboot.initrd:
-
-floppy:
-
-zImage:
-
-zImage.initrd:
-
-endif
-
-# just here to match coffboot/Makefile
-vmlinux.coff:
-
-vmlinux.coff.initrd:
-
-
-clean:
- rm -f piggyback note addnote $(OBJS) zImage
- rm -f zImage.rs6k zImage.initrd zImage.initrd.rs6k
-
-fastdep:
- $(TOPDIR)/scripts/mkdep *.[Sch] > .depend
-
-dep:
- $(CPP) $(CPPFLAGS) -M *.S *.c > .depend
-
+++ /dev/null
-/*
- * Program to hack in a PT_NOTE program header entry in an ELF file.
- * This is needed for OF on RS/6000s to load an image correctly.
- * Note that OF needs a program header entry for the note, not an
- * ELF section.
- *
- * Copyright 2000 Paul Mackerras.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Usage: addnote zImage
- */
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-
-char arch[] = "PowerPC";
-
-#define N_DESCR 6
-unsigned int descr[N_DESCR] = {
-#if 1
- /* values for IBM RS/6000 machines */
- 0xffffffff, /* real-mode = true */
- 0x00c00000, /* real-base, i.e. where we expect OF to be */
- 0xffffffff, /* real-size */
- 0xffffffff, /* virt-base */
- 0xffffffff, /* virt-size */
- 0x4000, /* load-base */
-#else
- /* values for longtrail CHRP */
- 0, /* real-mode = false */
- 0xffffffff, /* real-base */
- 0xffffffff, /* real-size */
- 0xffffffff, /* virt-base */
- 0xffffffff, /* virt-size */
- 0x00600000, /* load-base */
-#endif
-};
-
-unsigned char buf[512];
-
-#define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1]))
-#define GET_32BE(off) ((GET_16BE(off) << 16) + GET_16BE((off)+2))
-
-#define PUT_16BE(off, v) (buf[off] = ((v) >> 8) & 0xff, \
- buf[(off) + 1] = (v) & 0xff)
-#define PUT_32BE(off, v) (PUT_16BE((off), (v) >> 16), \
- PUT_16BE((off) + 2, (v)))
-
-/* Structure of an ELF file */
-#define E_IDENT 0 /* ELF header */
-#define E_PHOFF 28
-#define E_PHENTSIZE 42
-#define E_PHNUM 44
-#define E_HSIZE 52 /* size of ELF header */
-
-#define EI_MAGIC 0 /* offsets in E_IDENT area */
-#define EI_CLASS 4
-#define EI_DATA 5
-
-#define PH_TYPE 0 /* ELF program header */
-#define PH_OFFSET 4
-#define PH_FILESZ 16
-#define PH_HSIZE 32 /* size of program header */
-
-#define PT_NOTE 4 /* Program header type = note */
-
-#define ELFCLASS32 1
-#define ELFDATA2MSB 2
-
-unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' };
-
-int main(int ac, char **av)
-{
- int fd, n, i;
- int ph, ps, np;
- int nnote, ns;
-
- if (ac != 2) {
- fprintf(stderr, "Usage: %s elf-file\n", av[0]);
- exit(1);
- }
- fd = open(av[1], O_RDWR);
- if (fd < 0) {
- perror(av[1]);
- exit(1);
- }
-
- nnote = strlen(arch) + 1 + (N_DESCR + 3) * 4;
-
- n = read(fd, buf, sizeof(buf));
- if (n < 0) {
- perror("read");
- exit(1);
- }
-
- if (n < E_HSIZE || memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0)
- goto notelf;
-
- if (buf[E_IDENT+EI_CLASS] != ELFCLASS32
- || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) {
- fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n",
- av[1]);
- exit(1);
- }
-
- ph = GET_32BE(E_PHOFF);
- ps = GET_16BE(E_PHENTSIZE);
- np = GET_16BE(E_PHNUM);
- if (ph < E_HSIZE || ps < PH_HSIZE || np < 1)
- goto notelf;
- if (ph + (np + 1) * ps + nnote > n)
- goto nospace;
-
- for (i = 0; i < np; ++i) {
- if (GET_32BE(ph + PH_TYPE) == PT_NOTE) {
- fprintf(stderr, "%s already has a note entry\n",
- av[1]);
- exit(0);
- }
- ph += ps;
- }
-
- /* XXX check that the area we want to use is all zeroes */
- for (i = 0; i < ps + nnote; ++i)
- if (buf[ph + i] != 0)
- goto nospace;
-
- /* fill in the program header entry */
- ns = ph + ps;
- PUT_32BE(ph + PH_TYPE, PT_NOTE);
- PUT_32BE(ph + PH_OFFSET, ns);
- PUT_32BE(ph + PH_FILESZ, nnote);
-
- /* fill in the note area we point to */
- /* XXX we should probably make this a proper section */
- PUT_32BE(ns, strlen(arch) + 1);
- PUT_32BE(ns + 4, N_DESCR * 4);
- PUT_32BE(ns + 8, 0x1275);
- strcpy(&buf[ns + 12], arch);
- ns += 12 + strlen(arch) + 1;
- for (i = 0; i < N_DESCR; ++i)
- PUT_32BE(ns + i * 4, descr[i]);
-
- /* Update the number of program headers */
- PUT_16BE(E_PHNUM, np + 1);
-
- /* write back */
- lseek(fd, (long) 0, SEEK_SET);
- i = write(fd, buf, n);
- if (i < 0) {
- perror("write");
- exit(1);
- }
- if (i < n) {
- fprintf(stderr, "%s: write truncated\n", av[1]);
- exit(1);
- }
-
- exit(0);
-
- notelf:
- fprintf(stderr, "%s does not appear to be an ELF file\n", av[0]);
- exit(1);
-
- nospace:
- fprintf(stderr, "sorry, I can't find space in %s to put the note\n",
- av[0]);
- exit(1);
-}
+++ /dev/null
-/*
- * Copyright (C) Paul Mackerras 1997.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
- .text
- .globl _start
-_start:
- lis 9,_start@h
- lis 8,_etext@ha
- addi 8,8,_etext@l
-1: dcbf 0,9
- icbi 0,9
- addi 9,9,0x20
- cmplw 0,9,8
- blt 1b
- sync
- isync
- b start
+++ /dev/null
-/*
- * Copyright (C) Paul Mackerras 1997.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include "../coffboot/nonstdio.h"
-#include "../coffboot/zlib.h"
-#include <asm/bootinfo.h>
-#include <asm/processor.h>
-#include <asm/page.h>
-
-extern void *finddevice(const char *);
-extern int getprop(void *, const char *, void *, int);
-void gunzip(void *, int, unsigned char *, int *);
-
-#define RAM_START 0x00000000
-#define RAM_END (64<<20)
-
-#define BOOT_START ((unsigned long)_start)
-#define BOOT_END ((unsigned long)(_end + 0xFFF) & ~0xFFF)
-
-#define RAM_FREE ((unsigned long)(_end+0x1000)&~0xFFF)
-#define PROG_START 0x00010000
-
-char *avail_ram;
-char *end_avail;
-
-extern char _end[];
-extern char image_data[];
-extern int image_len;
-extern char initrd_data[];
-extern int initrd_len;
-extern char sysmap_data[];
-extern int sysmap_len;
-
-static char scratch[1024<<10]; /* 1MB of scratch space for gunzip */
-
-chrpboot(int a1, int a2, void *prom)
-{
- int ns, oh, i;
- unsigned sa, len;
- void *dst;
- unsigned char *im;
- unsigned initrd_start, initrd_size;
- extern char _start;
-
- printf("chrpboot starting: loaded at 0x%x\n\r", &_start);
-
- if (initrd_len) {
- initrd_size = initrd_len;
- initrd_start = (RAM_END - initrd_size) & ~0xFFF;
- a1 = initrd_start;
- a2 = initrd_size;
- claim(initrd_start, RAM_END - initrd_start, 0);
- printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n\r",
- initrd_start, initrd_data, initrd_size);
- memcpy((char *)initrd_start, initrd_data, initrd_size);
- }
-
- im = image_data;
- len = image_len;
- /* claim 4MB starting at PROG_START */
- claim(PROG_START, (4<<20) - PROG_START, 0);
- dst = (void *) PROG_START;
- if (im[0] == 0x1f && im[1] == 0x8b) {
- avail_ram = scratch;
- end_avail = scratch + sizeof(scratch);
- printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
- gunzip(dst, 0x400000, im, &len);
- printf("done %u bytes\n\r", len);
- } else {
- memmove(dst, im, len);
- }
-
- flush_cache(dst, len);
-
- sa = (unsigned long)PROG_START;
- printf("start address = 0x%x\n\r", sa);
-
- {
- struct bi_record *rec;
-
- rec = (struct bi_record *)_ALIGN((unsigned long)dst+len+(1<<20)-1,(1<<20));
-
- rec->tag = BI_FIRST;
- rec->size = sizeof(struct bi_record);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
- rec->tag = BI_BOOTLOADER_ID;
- sprintf( (char *)rec->data, "chrpboot");
- rec->size = sizeof(struct bi_record) + strlen("chrpboot") + 1;
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
- rec->tag = BI_MACHTYPE;
- rec->data[0] = _MACH_chrp;
- rec->data[1] = 1;
- rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
-#if 0
- rec->tag = BI_SYSMAP;
- rec->data[0] = (unsigned long)sysmap_data;
- rec->data[1] = sysmap_len;
- rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
-#endif
- rec->tag = BI_LAST;
- rec->size = sizeof(struct bi_record);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
- }
- (*(void (*)())sa)(a1, a2, prom);
-
- printf("returned?\n\r");
-
- pause();
-}
-
-void *zalloc(void *x, unsigned items, unsigned size)
-{
- void *p = avail_ram;
-
- size *= items;
- size = (size + 7) & -8;
- avail_ram += size;
- if (avail_ram > end_avail) {
- printf("oops... out of memory\n\r");
- pause();
- }
- return p;
-}
-
-void zfree(void *x, void *addr, unsigned nb)
-{
- nb = (nb + 7) & -8;
- if (addr == (avail_ram - nb)) {
- avail_ram -= nb;
- }
-}
-
-#define HEAD_CRC 2
-#define EXTRA_FIELD 4
-#define ORIG_NAME 8
-#define COMMENT 0x10
-#define RESERVED 0xe0
-
-#define DEFLATED 8
-
-void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
-{
- z_stream s;
- int r, i, flags;
-
- /* skip header */
- i = 10;
- flags = src[3];
- if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
- printf("bad gzipped data\n\r");
- exit();
- }
- if ((flags & EXTRA_FIELD) != 0)
- i = 12 + src[10] + (src[11] << 8);
- if ((flags & ORIG_NAME) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & COMMENT) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & HEAD_CRC) != 0)
- i += 2;
- if (i >= *lenp) {
- printf("gunzip: ran out of data in header\n\r");
- exit();
- }
-
- s.zalloc = zalloc;
- s.zfree = zfree;
- r = inflateInit2(&s, -MAX_WBITS);
- if (r != Z_OK) {
- printf("inflateInit2 returned %d\n\r", r);
- exit();
- }
- s.next_in = src + i;
- s.avail_in = *lenp - i;
- s.next_out = dst;
- s.avail_out = dstlen;
- r = inflate(&s, Z_FINISH);
- if (r != Z_OK && r != Z_STREAM_END) {
- printf("inflate returned %d msg: %s\n\r", r, s.msg);
- exit();
- }
- *lenp = s.next_out - (unsigned char *) dst;
- inflateEnd(&s);
-}
+++ /dev/null
-/*
- * Copyright (C) Paul Mackerras 1997.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
- .text
-
-/*
- * Use the BAT0 registers to map the 1st 8MB of RAM to 0x90000000.
- */
- .globl setup_bats
-setup_bats:
- mfpvr 3
- rlwinm 3,3,16,16,31 /* r3 = 1 for 601, 4 for 604 */
- cmpi 0,3,1
- lis 4,0x9000
- bne 4f
- ori 4,4,4 /* set up BAT registers for 601 */
- li 5,0x7f
- b 5f
-4: ori 4,4,0xff /* set up BAT registers for 604 */
- li 5,2
- mtdbatu 3,4
- mtdbatl 3,5
-5: mtibatu 3,4
- mtibatl 3,5
- isync
- blr
-
-/*
- * Flush the dcache and invalidate the icache for a range of addresses.
- *
- * flush_cache(addr, len)
- */
- .global flush_cache
-flush_cache:
- addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */
- rlwinm. 4,4,27,5,31
- mtctr 4
- beqlr
-1: dcbf 0,3
- icbi 0,3
- addi 3,3,0x20
- bdnz 1b
- sync
- isync
- blr
+++ /dev/null
-/*
- * Copyright (C) Cort Dougan 1999.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Generate a note section as per the CHRP specification.
- *
- */
-
-#include <stdio.h>
-
-#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff );
-
-int main(void)
-{
-/* header */
- /* namesz */
- PL(strlen("PowerPC")+1);
- /* descrsz */
- PL(6*4);
- /* type */
- PL(0x1275);
- /* name */
- printf("PowerPC"); printf("%c", 0);
-
-/* descriptor */
- /* real-mode */
- PL(0xffffffff);
- /* real-base */
- PL(0x00c00000);
- /* real-size */
- PL(0xffffffff);
- /* virt-base */
- PL(0xffffffff);
- /* virt-size */
- PL(0xffffffff);
- /* load-base */
- PL(0x4000);
- return 0;
-}
+++ /dev/null
-char initrd_data[1];
-int initrd_len = 0;
+++ /dev/null
-#include <stdio.h>
-#include <unistd.h>
-
-extern long ce_exec_config[];
-
-int main(int argc, char *argv[])
-{
- int i, cnt, pos, len;
- unsigned int cksum, val;
- unsigned char *lp;
- unsigned char buf[8192];
- if (argc != 2)
- {
- fprintf(stderr, "usage: %s name <in-file >out-file\n",
- argv[0]);
- exit(1);
- }
- fprintf(stdout, "#\n");
- fprintf(stdout, "# Miscellaneous data structures:\n");
- fprintf(stdout, "# WARNING - this file is automatically generated!\n");
- fprintf(stdout, "#\n");
- fprintf(stdout, "\n");
- fprintf(stdout, "\t.data\n");
- fprintf(stdout, "\t.globl %s_data\n", argv[1]);
- fprintf(stdout, "%s_data:\n", argv[1]);
- pos = 0;
- cksum = 0;
- while ((len = read(0, buf, sizeof(buf))) > 0)
- {
- cnt = 0;
- lp = (unsigned char *)buf;
- len = (len + 3) & ~3; /* Round up to longwords */
- for (i = 0; i < len; i += 4)
- {
- if (cnt == 0)
- {
- fprintf(stdout, "\t.long\t");
- }
- fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
- val = *(unsigned long *)lp;
- cksum ^= val;
- lp += 4;
- if (++cnt == 4)
- {
- cnt = 0;
- fprintf(stdout, " # %x \n", pos+i-12);
- fflush(stdout);
- } else
- {
- fprintf(stdout, ",");
- }
- }
- if (cnt)
- {
- fprintf(stdout, "0\n");
- }
- pos += len;
- }
- fprintf(stdout, "\t.globl %s_len\n", argv[1]);
- fprintf(stdout, "%s_len:\t.long\t0x%x\n", argv[1], pos);
- fflush(stdout);
- fclose(stdout);
- fprintf(stderr, "cksum = %x\n", cksum);
- exit(0);
-}
-
+++ /dev/null
-/*
- * Copyright (C) Paul Mackerras 1997.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include <stdarg.h>
-
-int (*prom)();
-
-void *chosen_handle;
-void *stdin;
-void *stdout;
-void *stderr;
-
-void exit(void);
-void *finddevice(const char *name);
-int getprop(void *phandle, const char *name, void *buf, int buflen);
-
-void printk(char *fmt, ...);
-
-void
-start(int a1, int a2, void *promptr)
-{
- prom = (int (*)()) promptr;
- chosen_handle = finddevice("/chosen");
- if (chosen_handle == (void *) -1)
- exit();
- if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
- exit();
- stderr = stdout;
- if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
- exit();
-
- chrpboot(a1, a2, promptr);
- for (;;)
- exit();
-}
-
-int
-write(void *handle, void *ptr, int nb)
-{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- void *ihandle;
- void *addr;
- int len;
- int actual;
- } args;
-
- args.service = "write";
- args.nargs = 3;
- args.nret = 1;
- args.ihandle = handle;
- args.addr = ptr;
- args.len = nb;
- args.actual = -1;
- (*prom)(&args);
- return args.actual;
-}
-
-int
-read(void *handle, void *ptr, int nb)
-{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- void *ihandle;
- void *addr;
- int len;
- int actual;
- } args;
-
- args.service = "read";
- args.nargs = 3;
- args.nret = 1;
- args.ihandle = handle;
- args.addr = ptr;
- args.len = nb;
- args.actual = -1;
- (*prom)(&args);
- return args.actual;
-}
-
-void
-exit()
-{
- struct prom_args {
- char *service;
- } args;
-
- for (;;) {
- args.service = "exit";
- (*prom)(&args);
- }
-}
-
-void
-pause()
-{
- struct prom_args {
- char *service;
- } args;
-
- args.service = "enter";
- (*prom)(&args);
-}
-
-void *
-finddevice(const char *name)
-{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- const char *devspec;
- void *phandle;
- } args;
-
- args.service = "finddevice";
- args.nargs = 1;
- args.nret = 1;
- args.devspec = name;
- args.phandle = (void *) -1;
- (*prom)(&args);
- return args.phandle;
-}
-
-void *
-claim(unsigned int virt, unsigned int size, unsigned int align)
-{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- unsigned int virt;
- unsigned int size;
- unsigned int align;
- void *ret;
- } args;
-
- args.service = "claim";
- args.nargs = 3;
- args.nret = 1;
- args.virt = virt;
- args.size = size;
- args.align = align;
- (*prom)(&args);
- return args.ret;
-}
-
-int
-getprop(void *phandle, const char *name, void *buf, int buflen)
-{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- void *phandle;
- const char *name;
- void *buf;
- int buflen;
- int size;
- } args;
-
- args.service = "getprop";
- args.nargs = 4;
- args.nret = 1;
- args.phandle = phandle;
- args.name = name;
- args.buf = buf;
- args.buflen = buflen;
- args.size = -1;
- (*prom)(&args);
- return args.size;
-}
-
-int
-putc(int c, void *f)
-{
- char ch = c;
-
- if (c == '\n')
- putc('\r', f);
- return write(f, &ch, 1) == 1? c: -1;
-}
-
-int
-putchar(int c)
-{
- return putc(c, stdout);
-}
-
-int
-fputs(char *str, void *f)
-{
- int n = strlen(str);
-
- return write(f, str, n) == n? 0: -1;
-}
-
-int
-readchar()
-{
- char ch;
-
- for (;;) {
- switch (read(stdin, &ch, 1)) {
- case 1:
- return ch;
- case -1:
- printk("read(stdin) returned -1\r\n");
- return -1;
- }
- }
-}
-
-static char line[256];
-static char *lineptr;
-static int lineleft;
-
-int
-getchar()
-{
- int c;
-
- if (lineleft == 0) {
- lineptr = line;
- for (;;) {
- c = readchar();
- if (c == -1 || c == 4)
- break;
- if (c == '\r' || c == '\n') {
- *lineptr++ = '\n';
- putchar('\n');
- break;
- }
- switch (c) {
- case 0177:
- case '\b':
- if (lineptr > line) {
- putchar('\b');
- putchar(' ');
- putchar('\b');
- --lineptr;
- }
- break;
- case 'U' & 0x1F:
- while (lineptr > line) {
- putchar('\b');
- putchar(' ');
- putchar('\b');
- --lineptr;
- }
- break;
- default:
- if (lineptr >= &line[sizeof(line) - 1])
- putchar('\a');
- else {
- putchar(c);
- *lineptr++ = c;
- }
- }
- }
- lineleft = lineptr - line;
- lineptr = line;
- }
- if (lineleft == 0)
- return -1;
- --lineleft;
- return *lineptr++;
-}
-
-extern int vsprintf(char *buf, const char *fmt, va_list args);
-static char sprint_buf[1024];
-
-void
-printk(char *fmt, ...)
-{
- va_list args;
- int n;
-
- va_start(args, fmt);
- n = vsprintf(sprint_buf, fmt, args);
- va_end(args);
- write(stdout, sprint_buf, n);
-}
-
-int
-printf(char *fmt, ...)
-{
- va_list args;
- int n;
-
- va_start(args, fmt);
- n = vsprintf(sprint_buf, fmt, args);
- va_end(args);
- write(stdout, sprint_buf, n);
- return n;
-}
+++ /dev/null
-# Makefile for making XCOFF bootable images for booting on PowerMacs
-# using Open Firmware.
-#
-# Paul Mackerras January 1997
-
-HOSTCFLAGS = -O -I$(TOPDIR)/include
-
-CFLAGS = $(CPPFLAGS) -O -fno-builtin
-OBJCOPY_ARGS = -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment
-COFF_LD_ARGS = -e _start -T ld.script -Ttext 500000 -Tdata 510000 -Bstatic
-CHRP_LD_ARGS = -Ttext 0x01000000
-
-COFFOBJS = coffcrt0.o start.o coffmain.o misc.o string.o zlib.o image.o
-CHRPOBJS = crt0.o start.o chrpmain.o misc.o string.o zlib.o image.o
-LIBS = $(TOPDIR)/lib/lib.a
-
-ifeq ($(CONFIG_PPC64BRIDGE),y)
-MSIZE=.64
-else
-MSIZE=
-endif
-
-ifeq ($(CONFIG_SMP),y)
-TFTPIMAGE=/tftpboot/zImage.pmac.smp$(MSIZE)
-else
-TFTPIMAGE=/tftpboot/zImage.pmac$(MSIZE)
-endif
-
-ifeq ($(CONFIG_ALL_PPC),y)
-chrpmain.o: chrpmain.c
- $(CC) $(CFLAGS) -DSYSMAP_OFFSET=0 -DSYSMAP_SIZE=0 -c chrpmain.c
-
-hack-coff: hack-coff.c
- $(HOSTCC) $(HOSTCFLAGS) -o hack-coff hack-coff.c
-
-znetboot: vmlinux.coff vmlinux.elf zImage
- cp vmlinux.coff $(TFTPIMAGE)
- cp vmlinux.elf $(TFTPIMAGE).elf
-
-znetboot.initrd: vmlinux.coff.initrd vmlinux.elf.initrd
- cp vmlinux.coff.initrd $(TFTPIMAGE)
- cp vmlinux.elf.initrd $(TFTPIMAGE).elf
-
-floppy: zImage
-# mount -t hfs /dev/fd0 /mnt
-# cp vmlinux.coff /mnt
-# umount /mnt
-
-miboot.image: dummy.o vmlinux.gz
- $(OBJCOPY) $(OBJCOPY_ARGS) --add-section=image=vmlinux.gz dummy.o $@
-
-miboot.image.initrd: miboot.image ramdisk.image.gz
- $(OBJCOPY) $(OBJCOPY_ARGS) --add-section=initrd=ramdisk.image.gz miboot.image $@
-
-coffboot: $(COFFOBJS) no_initrd.o ld.script
- $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) no_initrd.o $(LIBS)
-
-coffboot.initrd: $(COFFOBJS) initrd.o ld.script
- $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) initrd.o $(LIBS)
-
-piggyback: piggyback.c
- $(HOSTCC) $(HOSTCFLAGS) -DKERNELBASE=$(KERNELBASE) -o piggyback piggyback.c
-
-mknote: mknote.c
- $(HOSTCC) $(HOSTCFLAGS) -o mknote mknote.c
-
-image.o: piggyback vmlinux.gz
- ./piggyback image < vmlinux.gz | $(AS) -o image.o
-
-initrd.o: ramdisk.image.gz piggyback
- ./piggyback initrd < ramdisk.image.gz | $(AS) -o initrd.o
-
-vmlinux.coff: coffboot hack-coff
- $(OBJCOPY) $(OBJCOPY_ARGS) coffboot $@
- ./hack-coff $@
- ln -sf vmlinux.coff zImage
-
-vmlinux.coff.initrd: coffboot.initrd hack-coff
- $(OBJCOPY) $(OBJCOPY_ARGS) coffboot.initrd $@
- ./hack-coff $@
-
-vmlinux.elf: $(CHRPOBJS) no_initrd.o mknote
- $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) no_initrd.o $(LIBS)
- ./mknote > note
- $(OBJCOPY) $@ $@ --add-section=.note=note \
- --add-section=sysmap=../../../System.map -R .comment
- $(CC) $(CFLAGS) chrpmain.c -c -o chrpmain.o \
- -DSYSMAP_OFFSET=`sh ../boot/offset $(OBJDUMP) $@ sysmap` \
- -DSYSMAP_SIZE=`sh ../boot/size $(OBJDUMP) $@ sysmap`
- $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) no_initrd.o $(LIBS)
- $(OBJCOPY) $@ $@ --add-section=.note=note \
- --add-section=sysmap=../../../System.map -R .comment
-
-vmlinux.elf.initrd: $(CHRPOBJS) initrd.o mknote
- $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) initrd.o $(LIBS)
- ./mknote > note
- $(OBJCOPY) $@ $@ --add-section=.note=note -R .comment
-
-zImage: vmlinux.coff vmlinux.elf miboot.image
-
-zImage.initrd: vmlinux.coff.initrd vmlinux.elf.initrd miboot.image.initrd
-
-else
-znetboot: vmlinux.gz
-
-znetboot.initrd: vmlinux.gz
-
-coffboot: vmlinux.gz
-
-zImage: vmlinux.gz
-
-zImage.initrd: vmlinux.gz
-
-vmlinux.coff: vmlinux.gz
-
-vmlinux.coff.initrd: vmlinux.gz
-
-floppy: vmlinux.gz
-
-endif
-
-vmlinux.gz: $(TOPDIR)/vmlinux
- $(OBJCOPY) -S -O binary $(TOPDIR)/vmlinux vmlinux
- gzip -vf9 vmlinux
-
-clean:
- rm -f hack-coff coffboot zImage vmlinux.coff vmlinux.gz
- rm -f mknote piggyback vmlinux.elf note
- rm -f miboot.image miboot.image.initrd
-
-fastdep:
+++ /dev/null
-/*
- * Copyright (C) Paul Mackerras 1997.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include "nonstdio.h"
-#include "zlib.h"
-#include <asm/bootinfo.h>
-#include <asm/processor.h>
-#include <asm/page.h>
-
-extern void *finddevice(const char *);
-extern int getprop(void *, const char *, void *, int);
-extern void *claim(unsigned int, unsigned int, unsigned int);
-extern void release(void *ptr, unsigned int len);
-void make_bi_recs(unsigned long);
-void gunzip(void *, int, unsigned char *, int *);
-void stop_imac_ethernet(void);
-void stop_imac_usb(void);
-
-#define get_16be(x) (*(unsigned short *)(x))
-#define get_32be(x) (*(unsigned *)(x))
-
-#define RAM_END (16 << 20)
-
-#define PROG_START 0x00010000
-#define PROG_SIZE 0x003f0000
-
-#define SCRATCH_SIZE (128 << 10)
-
-char *avail_ram;
-char *begin_avail, *end_avail;
-char *avail_high;
-unsigned int heap_use;
-unsigned int heap_max;
-
-extern char _end[];
-extern char image_data[];
-extern int image_len;
-extern char initrd_data[];
-extern int initrd_len;
-
-
-boot(int a1, int a2, void *prom)
-{
- int ns, oh, i;
- unsigned sa, len;
- void *dst;
- unsigned char *im;
- unsigned initrd_start, initrd_size;
- extern char _start;
-
- printf("chrpboot starting: loaded at 0x%x\n", &_start);
- if (initrd_len) {
- initrd_size = initrd_len;
- initrd_start = (RAM_END - initrd_size) & ~0xFFF;
- a1 = initrd_start;
- a2 = initrd_size;
- claim(initrd_start, RAM_END - initrd_start, 0);
- printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n", initrd_start,
- initrd_data,initrd_size);
- memcpy((char *)initrd_start, initrd_data, initrd_size);
- }
- im = image_data;
- len = image_len;
- /* claim 3MB starting at PROG_START */
- claim(PROG_START, PROG_SIZE, 0);
- dst = (void *) PROG_START;
- if (im[0] == 0x1f && im[1] == 0x8b) {
- /* claim some memory for scratch space */
- avail_ram = (char *) claim(0, SCRATCH_SIZE, 0x10);
- begin_avail = avail_high = avail_ram;
- end_avail = avail_ram + SCRATCH_SIZE;
- printf("heap at 0x%x\n", avail_ram);
- printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
- gunzip(dst, PROG_SIZE, im, &len);
- printf("done %u bytes\n", len);
- printf("%u bytes of heap consumed, max in use %u\n",
- avail_high - begin_avail, heap_max);
- release(begin_avail, SCRATCH_SIZE);
- } else {
- memmove(dst, im, len);
- }
-
- flush_cache(dst, len);
- make_bi_recs((unsigned long) dst + len);
-
- sa = (unsigned long)PROG_START;
- printf("start address = 0x%x\n", sa);
-
- (*(void (*)())sa)(a1, a2, prom);
-
- printf("returned?\n");
-
- pause();
-}
-
-void make_bi_recs(unsigned long addr)
-{
- struct bi_record *rec;
-
- /* leave a 1MB gap then align to the next 1MB boundary */
- addr = _ALIGN(addr+ (1<<20) - 1, (1<<20));
- if (addr >= PROG_START + PROG_SIZE)
- claim(addr, 0x1000, 0);
-
- rec = (struct bi_record *)addr;
- rec->tag = BI_FIRST;
- rec->size = sizeof(struct bi_record);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
- rec->tag = BI_BOOTLOADER_ID;
- sprintf( (char *)rec->data, "coffboot");
- rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1;
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
- rec->tag = BI_MACHTYPE;
- rec->data[0] = _MACH_Pmac;
- rec->data[1] = 1;
- rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
-#ifdef SYSMAP_OFFSET
- rec->tag = BI_SYSMAP;
- rec->data[0] = SYSMAP_OFFSET;
- rec->data[1] = SYSMAP_SIZE;
- rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
-#endif /* SYSMAP_OFFSET */
-
- rec->tag = BI_LAST;
- rec->size = sizeof(struct bi_record);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
-}
-
-#if 0
-#define eieio() asm volatile("eieio");
-
-void stop_imac_ethernet(void)
-{
- void *macio, *enet;
- unsigned int macio_addr[5], enet_reg[6];
- int len;
- volatile unsigned int *dbdma;
-
- macio = finddevice("/pci/mac-io");
- enet = finddevice("/pci/mac-io/ethernet");
- if (macio == NULL || enet == NULL)
- return;
- len = getprop(macio, "assigned-addresses", macio_addr, sizeof(macio_addr));
- if (len != sizeof(macio_addr))
- return;
- len = getprop(enet, "reg", enet_reg, sizeof(enet_reg));
- if (len != sizeof(enet_reg))
- return;
- printf("macio base %x, dma at %x & %x\n",
- macio_addr[2], enet_reg[2], enet_reg[4]);
-
- /* hope this is mapped... */
- dbdma = (volatile unsigned int *) (macio_addr[2] + enet_reg[2]);
- *dbdma = 0x80; /* clear the RUN bit */
- eieio();
- dbdma = (volatile unsigned int *) (macio_addr[2] + enet_reg[4]);
- *dbdma = 0x80; /* clear the RUN bit */
- eieio();
-}
-
-void stop_imac_usb(void)
-{
- void *usb;
- unsigned int usb_addr[5];
- int len;
- volatile unsigned int *usb_ctrl;
-
- usb = finddevice("/pci/usb");
- if (usb == NULL)
- return;
- len = getprop(usb, "assigned-addresses", usb_addr, sizeof(usb_addr));
- if (len != sizeof(usb_addr))
- return;
- printf("usb base %x\n", usb_addr[2]);
-
- usb_ctrl = (volatile unsigned int *) (usb_addr[2] + 8);
- *usb_ctrl = 0x01000000; /* cpu_to_le32(1) */
- eieio();
-}
-#endif
-
-struct memchunk {
- unsigned int size;
- struct memchunk *next;
-};
-
-static struct memchunk *freechunks;
-
-void *zalloc(void *x, unsigned items, unsigned size)
-{
- void *p;
- struct memchunk **mpp, *mp;
-
- size *= items;
- size = (size + 7) & -8;
- heap_use += size;
- if (heap_use > heap_max)
- heap_max = heap_use;
- for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
- if (mp->size == size) {
- *mpp = mp->next;
- return mp;
- }
- }
- p = avail_ram;
- avail_ram += size;
- if (avail_ram > avail_high)
- avail_high = avail_ram;
- if (avail_ram > end_avail) {
- printf("oops... out of memory\n");
- pause();
- }
- return p;
-}
-
-void zfree(void *x, void *addr, unsigned nb)
-{
- struct memchunk *mp = addr;
-
- nb = (nb + 7) & -8;
- heap_use -= nb;
- if (avail_ram == addr + nb) {
- avail_ram = addr;
- return;
- }
- mp->size = nb;
- mp->next = freechunks;
- freechunks = mp;
-}
-
-#define HEAD_CRC 2
-#define EXTRA_FIELD 4
-#define ORIG_NAME 8
-#define COMMENT 0x10
-#define RESERVED 0xe0
-
-#define DEFLATED 8
-
-void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
-{
- z_stream s;
- int r, i, flags;
-
- /* skip header */
- i = 10;
- flags = src[3];
- if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
- printf("bad gzipped data\n");
- exit();
- }
- if ((flags & EXTRA_FIELD) != 0)
- i = 12 + src[10] + (src[11] << 8);
- if ((flags & ORIG_NAME) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & COMMENT) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & HEAD_CRC) != 0)
- i += 2;
- if (i >= *lenp) {
- printf("gunzip: ran out of data in header\n");
- exit();
- }
-
- s.zalloc = zalloc;
- s.zfree = zfree;
- r = inflateInit2(&s, -MAX_WBITS);
- if (r != Z_OK) {
- printf("inflateInit2 returned %d\n", r);
- exit();
- }
- s.next_in = src + i;
- s.avail_in = *lenp - i;
- s.next_out = dst;
- s.avail_out = dstlen;
- r = inflate(&s, Z_FINISH);
- if (r != Z_OK && r != Z_STREAM_END) {
- printf("inflate returned %d msg: %s\n", r, s.msg);
- exit();
- }
- *lenp = s.next_out - (unsigned char *) dst;
- inflateEnd(&s);
-}
+++ /dev/null
-/*
- * Copyright (C) Paul Mackerras 1997.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
- .text
- .globl _start
-_start:
- .long __start,0,0
-
- .globl __start
-__start:
- lis 9,_start@h
- lis 8,_etext@ha
- addi 8,8,_etext@l
-1: dcbf 0,9
- icbi 0,9
- addi 9,9,0x20
- cmplwi 0,9,8
- blt 1b
- b start
+++ /dev/null
-/*
- * Copyright (C) Paul Mackerras 1997.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include "nonstdio.h"
-#include "zlib.h"
-#include <asm/bootinfo.h>
-#include <asm/processor.h>
-#include <asm/page.h>
-
-extern void *finddevice(const char *);
-extern int getprop(void *, const char *, void *, int);
-extern char *claim(unsigned, unsigned, unsigned);
-void make_bi_recs(unsigned long);
-void gunzip(void *, int, unsigned char *, int *);
-
-#define get_16be(x) (*(unsigned short *)(x))
-#define get_32be(x) (*(unsigned *)(x))
-
-#define RAM_START 0xc0000000
-#define RAM_END (RAM_START + 0x800000) /* only 8M mapped with BATs */
-
-#define PROG_START RAM_START
-#define PROG_SIZE 0x00400000
-
-#define SCRATCH_SIZE (128 << 10)
-
-char *avail_ram;
-char *begin_avail, *end_avail;
-char *avail_high;
-unsigned int heap_use;
-unsigned int heap_max;
-
-extern char _start[], _end[];
-extern char image_data[];
-extern int image_len;
-extern char initrd_data[];
-extern int initrd_len;
-
-char heap[SCRATCH_SIZE];
-
-boot(int a1, int a2, void *prom)
-{
- int ns, oh, i;
- unsigned sa, len;
- void *dst;
- unsigned char *im;
- unsigned initrd_start, initrd_size;
-
- printf("coffboot starting: loaded at 0x%x\n", _start);
- setup_bats(RAM_START);
- if (initrd_len) {
- initrd_size = initrd_len;
- initrd_start = (RAM_END - initrd_size) & ~0xFFF;
- a1 = initrd_start;
- a2 = initrd_size;
- claim(initrd_start - RAM_START, RAM_END - initrd_start, 0);
- printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n",
- initrd_start, initrd_data, initrd_size);
- memcpy((char *)initrd_start, initrd_data, initrd_size);
- }
- im = image_data;
- len = image_len;
- /* claim 3MB starting at 0 */
- claim(0, PROG_SIZE, 0);
- dst = (void *) RAM_START;
- if (im[0] == 0x1f && im[1] == 0x8b) {
- /* claim some memory for scratch space */
- begin_avail = avail_high = avail_ram = heap;
- end_avail = heap + sizeof(heap);
- printf("heap at 0x%x\n", avail_ram);
- printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
- gunzip(dst, PROG_SIZE, im, &len);
- printf("done %u bytes\n", len);
- printf("%u bytes of heap consumed, max in use %u\n",
- avail_high - begin_avail, heap_max);
- } else {
- memmove(dst, im, len);
- }
-
- flush_cache(dst, len);
- make_bi_recs((unsigned long)dst + len);
-
- sa = (unsigned long)PROG_START;
- printf("start address = 0x%x\n", sa);
-
- (*(void (*)())sa)(a1, a2, prom);
-
- printf("returned?\n");
-
- pause();
-}
-
-void make_bi_recs(unsigned long addr)
-{
- struct bi_record *rec;
-
- rec = (struct bi_record *)PAGE_ALIGN(addr);
-
- rec->tag = BI_FIRST;
- rec->size = sizeof(struct bi_record);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
- rec->tag = BI_BOOTLOADER_ID;
- sprintf( (char *)rec->data, "coffboot");
- rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1;
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
- rec->tag = BI_MACHTYPE;
- rec->data[0] = _MACH_Pmac;
- rec->data[1] = 1;
- rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
- rec->tag = BI_LAST;
- rec->size = sizeof(struct bi_record);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
-}
-
-struct memchunk {
- unsigned int size;
- struct memchunk *next;
-};
-
-static struct memchunk *freechunks;
-
-void *zalloc(void *x, unsigned items, unsigned size)
-{
- void *p;
- struct memchunk **mpp, *mp;
-
- size *= items;
- size = (size + 7) & -8;
- heap_use += size;
- if (heap_use > heap_max)
- heap_max = heap_use;
- for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
- if (mp->size == size) {
- *mpp = mp->next;
- return mp;
- }
- }
- p = avail_ram;
- avail_ram += size;
- if (avail_ram > avail_high)
- avail_high = avail_ram;
- if (avail_ram > end_avail) {
- printf("oops... out of memory\n");
- pause();
- }
- return p;
-}
-
-void zfree(void *x, void *addr, unsigned nb)
-{
- struct memchunk *mp = addr;
-
- nb = (nb + 7) & -8;
- heap_use -= nb;
- if (avail_ram == addr + nb) {
- avail_ram = addr;
- return;
- }
- mp->size = nb;
- mp->next = freechunks;
- freechunks = mp;
-}
-
-#define HEAD_CRC 2
-#define EXTRA_FIELD 4
-#define ORIG_NAME 8
-#define COMMENT 0x10
-#define RESERVED 0xe0
-
-#define DEFLATED 8
-
-void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
-{
- z_stream s;
- int r, i, flags;
-
- /* skip header */
- i = 10;
- flags = src[3];
- if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
- printf("bad gzipped data\n");
- exit();
- }
- if ((flags & EXTRA_FIELD) != 0)
- i = 12 + src[10] + (src[11] << 8);
- if ((flags & ORIG_NAME) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & COMMENT) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & HEAD_CRC) != 0)
- i += 2;
- if (i >= *lenp) {
- printf("gunzip: ran out of data in header\n");
- exit();
- }
-
- s.zalloc = zalloc;
- s.zfree = zfree;
- r = inflateInit2(&s, -MAX_WBITS);
- if (r != Z_OK) {
- printf("inflateInit2 returned %d\n", r);
- exit();
- }
- s.next_in = src + i;
- s.avail_in = *lenp - i;
- s.next_out = dst;
- s.avail_out = dstlen;
- r = inflate(&s, Z_FINISH);
- if (r != Z_OK && r != Z_STREAM_END) {
- printf("inflate returned %d msg: %s\n", r, s.msg);
- exit();
- }
- *lenp = s.next_out - (unsigned char *) dst;
- inflateEnd(&s);
-}
+++ /dev/null
-/*
- * Copyright (C) Paul Mackerras 1997.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
- .text
- .globl _start
-_start:
- lis 9,_start@h
- lis 8,_etext@ha
- addi 8,8,_etext@l
-1: dcbf 0,9
- icbi 0,9
- addi 9,9,0x20
- cmplwi 0,9,8
- blt 1b
- b start
+++ /dev/null
-int main(void)
-{
- return 0;
-}
+++ /dev/null
-/*
- * hack-coff.c - hack the header of an xcoff file to fill in
- * a few fields needed by the Open Firmware xcoff loader on
- * Power Macs but not initialized by objcopy.
- *
- * Copyright (C) Paul Mackerras 1997.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include <stdio.h>
-#include "rs6000.h"
-
-#define AOUT_MAGIC 0x010b
-
-#define get_16be(x) ((((unsigned char *)(x))[0] << 8) \
- + ((unsigned char *)(x))[1])
-#define put_16be(x, v) (((unsigned char *)(x))[0] = (v) >> 8, \
- ((unsigned char *)(x))[1] = (v) & 0xff)
-#define get_32be(x) ((((unsigned char *)(x))[0] << 24) \
- + (((unsigned char *)(x))[1] << 16) \
- + (((unsigned char *)(x))[2] << 8) \
- + ((unsigned char *)(x))[3])
-
-main(int ac, char **av)
-{
- int fd;
- int i, nsect;
- int aoutsz;
- struct external_filehdr fhdr;
- AOUTHDR aout;
- struct external_scnhdr shdr;
-
- if (ac != 2) {
- fprintf(stderr, "Usage: hack-coff coff-file\n");
- exit(1);
- }
- if ((fd = open(av[1], 2)) == -1) {
- perror(av[2]);
- exit(1);
- }
- if (read(fd, &fhdr, sizeof(fhdr)) != sizeof(fhdr))
- goto readerr;
- i = get_16be(fhdr.f_magic);
- if (i != U802TOCMAGIC && i != U802WRMAGIC && i != U802ROMAGIC) {
- fprintf(stderr, "%s: not an xcoff file\n", av[1]);
- exit(1);
- }
- aoutsz = get_16be(fhdr.f_opthdr);
- if (read(fd, &aout, aoutsz) != aoutsz)
- goto readerr;
- nsect = get_16be(fhdr.f_nscns);
- for (i = 0; i < nsect; ++i) {
- if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr))
- goto readerr;
- if (strcmp(shdr.s_name, ".text") == 0) {
- put_16be(aout.o_snentry, i+1);
- put_16be(aout.o_sntext, i+1);
- } else if (strcmp(shdr.s_name, ".data") == 0) {
- put_16be(aout.o_sndata, i+1);
- } else if (strcmp(shdr.s_name, ".bss") == 0) {
- put_16be(aout.o_snbss, i+1);
- }
- }
- put_16be(aout.magic, AOUT_MAGIC);
- if (lseek(fd, (long) sizeof(struct external_filehdr), 0) == -1
- || write(fd, &aout, aoutsz) != aoutsz) {
- fprintf(stderr, "%s: write error\n", av[1]);
- exit(1);
- }
- close(fd);
- exit(0);
-
-readerr:
- fprintf(stderr, "%s: read error or file too short\n", av[1]);
- exit(1);
-}
+++ /dev/null
-OUTPUT_ARCH(powerpc)
-SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
-/* Do we need any of these for elf?
- __DYNAMIC = 0; */
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- . = + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .rel.text : { *(.rel.text) }
- .rela.text : { *(.rela.text) }
- .rel.data : { *(.rel.data) }
- .rela.data : { *(.rela.data) }
- .rel.rodata : { *(.rel.rodata) }
- .rela.rodata : { *(.rela.rodata) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.bss : { *(.rel.bss) }
- .rela.bss : { *(.rela.bss) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .init : { *(.init) } =0
- .plt : { *(.plt) }
- .text :
- {
- *(.text)
- *(.rodata)
- *(.rodata1)
- *(.got1)
- }
- .fini : { *(.fini) } =0
- .ctors : { *(.ctors) }
- .dtors : { *(.dtors) }
- _etext = .;
- PROVIDE (etext = .);
- /* Read-write section, merged into data segment: */
- . = (. + 0x0FFF) & 0xFFFFF000;
- .data :
- {
- *(.data)
- *(.data1)
- *(.sdata)
- *(.sdata2)
- *(.got.plt) *(.got)
- *(.dynamic)
- CONSTRUCTORS
- }
- _edata = .;
- PROVIDE (edata = .);
- __bss_start = .;
- .bss :
- {
- *(.sbss) *(.scommon)
- *(.dynbss)
- *(.bss)
- *(COMMON)
- }
- _end = . ;
- PROVIDE (end = .);
-}
-
+++ /dev/null
-/*
- * Copyright (C) Paul Mackerras 1997.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
- .text
-
-/*
- * Use the BAT3 registers to map the 1st 8MB of RAM to
- * the address given as the 1st argument.
- */
- .globl setup_bats
-setup_bats:
- mfpvr 5
- rlwinm 5,5,16,16,31 /* r3 = 1 for 601, 4 for 604 */
- cmpi 0,5,1
- li 0,0
- bne 4f
- mtibatl 3,0 /* invalidate BAT first */
- ori 3,3,4 /* set up BAT registers for 601 */
- li 4,0x7f
- mtibatu 3,3
- mtibatl 3,4
- b 5f
-4: mtdbatu 3,0 /* invalidate BATs first */
- mtibatu 3,0
- ori 3,3,0xff /* set up BAT registers for 604 */
- li 4,2
- mtdbatl 3,4
- mtdbatu 3,3
- mtibatl 3,4
- mtibatu 3,3
-5: sync
- isync
- blr
-
-/*
- * Flush the dcache and invalidate the icache for a range of addresses.
- *
- * flush_cache(addr, len)
- */
- .global flush_cache
-flush_cache:
- addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */
- rlwinm. 4,4,27,5,31
- mtctr 4
- beqlr
-1: dcbf 0,3
- icbi 0,3
- addi 3,3,0x20
- bdnz 1b
- sync
- isync
- blr
+++ /dev/null
-/*
- * Copyright (C) Cort Dougan 1999.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Generate a note section as per the CHRP specification.
- *
- */
-
-#include <stdio.h>
-
-#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff );
-
-int main(void)
-{
-/* header */
- /* namesz */
- PL(strlen("PowerPC")+1);
- /* descrsz */
- PL(6*4);
- /* type */
- PL(0x1275);
- /* name */
- printf("PowerPC"); printf("%c", 0);
-
-/* descriptor */
- /* real-mode */
- PL(0xffffffff);
- /* real-base */
- PL(0x00c00000);
- /* real-size */
- PL(0xffffffff);
- /* virt-base */
- PL(0xffffffff);
- /* virt-size */
- PL(0xffffffff);
- /* load-base */
- PL(0x4000);
- return 0;
-}
+++ /dev/null
-char initrd_data[1];
-int initrd_len = 0;
+++ /dev/null
-/*
- * Copyright (C) Paul Mackerras 1997.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-typedef int FILE;
-extern FILE *stdin, *stdout;
-#define NULL ((void *)0)
-#define EOF (-1)
-#define fopen(n, m) NULL
-#define fflush(f) 0
-#define fclose(f) 0
-extern char *fgets();
-
-#define perror(s) printf("%s: no files!\n", (s))
+++ /dev/null
-#include <stdio.h>
-#include <unistd.h>
-
-extern long ce_exec_config[];
-
-int main(int argc, char *argv[])
-{
- int i, cnt, pos, len;
- unsigned int cksum, val;
- unsigned char *lp;
- unsigned char buf[8192];
- if (argc != 2)
- {
- fprintf(stderr, "usage: %s name <in-file >out-file\n",
- argv[0]);
- exit(1);
- }
- fprintf(stdout, "#\n");
- fprintf(stdout, "# Miscellaneous data structures:\n");
- fprintf(stdout, "# WARNING - this file is automatically generated!\n");
- fprintf(stdout, "#\n");
- fprintf(stdout, "\n");
- fprintf(stdout, "\t.data\n");
- fprintf(stdout, "\t.globl %s_data\n", argv[1]);
- fprintf(stdout, "%s_data:\n", argv[1]);
- pos = 0;
- cksum = 0;
- while ((len = read(0, buf, sizeof(buf))) > 0)
- {
- cnt = 0;
- lp = (unsigned char *)buf;
- len = (len + 3) & ~3; /* Round up to longwords */
- for (i = 0; i < len; i += 4)
- {
- if (cnt == 0)
- {
- fprintf(stdout, "\t.long\t");
- }
- fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
- val = *(unsigned long *)lp;
- cksum ^= val;
- lp += 4;
- if (++cnt == 4)
- {
- cnt = 0;
- fprintf(stdout, " # %x \n", pos+i-12);
- fflush(stdout);
- } else
- {
- fprintf(stdout, ",");
- }
- }
- if (cnt)
- {
- fprintf(stdout, "0\n");
- }
- pos += len;
- }
- fprintf(stdout, "\t.globl %s_len\n", argv[1]);
- fprintf(stdout, "%s_len:\t.long\t0x%x\n", argv[1], pos);
- fflush(stdout);
- fclose(stdout);
- fprintf(stderr, "cksum = %x\n", cksum);
- exit(0);
-}
-
+++ /dev/null
-/* IBM RS/6000 "XCOFF" file definitions for BFD.
- Copyright (C) 1990, 1991 Free Software Foundation, Inc.
- FIXME: Can someone provide a transliteration of this name into ASCII?
- Using the following chars caused a compiler warning on HIUX (so I replaced
- them with octal escapes), and isn't useful without an understanding of what
- character set it is.
- Written by Mimi Ph\373\364ng-Th\345o V\365 of IBM
- and John Gilmore of Cygnus Support. */
-
-/********************** FILE HEADER **********************/
-
-struct external_filehdr {
- char f_magic[2]; /* magic number */
- char f_nscns[2]; /* number of sections */
- char f_timdat[4]; /* time & date stamp */
- char f_symptr[4]; /* file pointer to symtab */
- char f_nsyms[4]; /* number of symtab entries */
- char f_opthdr[2]; /* sizeof(optional hdr) */
- char f_flags[2]; /* flags */
-};
-
- /* IBM RS/6000 */
-#define U802WRMAGIC 0730 /* writeable text segments **chh** */
-#define U802ROMAGIC 0735 /* readonly sharable text segments */
-#define U802TOCMAGIC 0737 /* readonly text segments and TOC */
-
-#define BADMAG(x) \
- ((x).f_magic != U802ROMAGIC && (x).f_magic != U802WRMAGIC && \
- (x).f_magic != U802TOCMAGIC)
-
-#define FILHDR struct external_filehdr
-#define FILHSZ 20
-
-
-/********************** AOUT "OPTIONAL HEADER" **********************/
-
-
-typedef struct
-{
- unsigned char magic[2]; /* type of file */
- unsigned char vstamp[2]; /* version stamp */
- unsigned char tsize[4]; /* text size in bytes, padded to FW bdry */
- unsigned char dsize[4]; /* initialized data " " */
- unsigned char bsize[4]; /* uninitialized data " " */
- unsigned char entry[4]; /* entry pt. */
- unsigned char text_start[4]; /* base of text used for this file */
- unsigned char data_start[4]; /* base of data used for this file */
- unsigned char o_toc[4]; /* address of TOC */
- unsigned char o_snentry[2]; /* section number of entry point */
- unsigned char o_sntext[2]; /* section number of .text section */
- unsigned char o_sndata[2]; /* section number of .data section */
- unsigned char o_sntoc[2]; /* section number of TOC */
- unsigned char o_snloader[2]; /* section number of .loader section */
- unsigned char o_snbss[2]; /* section number of .bss section */
- unsigned char o_algntext[2]; /* .text alignment */
- unsigned char o_algndata[2]; /* .data alignment */
- unsigned char o_modtype[2]; /* module type (??) */
- unsigned char o_cputype[2]; /* cpu type */
- unsigned char o_maxstack[4]; /* max stack size (??) */
- unsigned char o_maxdata[4]; /* max data size (??) */
- unsigned char o_resv2[12]; /* reserved */
-}
-AOUTHDR;
-
-#define AOUTSZ 72
-#define SMALL_AOUTSZ (28)
-#define AOUTHDRSZ 72
-
-#define RS6K_AOUTHDR_OMAGIC 0x0107 /* old: text & data writeable */
-#define RS6K_AOUTHDR_NMAGIC 0x0108 /* new: text r/o, data r/w */
-#define RS6K_AOUTHDR_ZMAGIC 0x010B /* paged: text r/o, both page-aligned */
-
-
-/********************** SECTION HEADER **********************/
-
-
-struct external_scnhdr {
- char s_name[8]; /* section name */
- char s_paddr[4]; /* physical address, aliased s_nlib */
- char s_vaddr[4]; /* virtual address */
- char s_size[4]; /* section size */
- char s_scnptr[4]; /* file ptr to raw data for section */
- char s_relptr[4]; /* file ptr to relocation */
- char s_lnnoptr[4]; /* file ptr to line numbers */
- char s_nreloc[2]; /* number of relocation entries */
- char s_nlnno[2]; /* number of line number entries*/
- char s_flags[4]; /* flags */
-};
-
-/*
- * names of "special" sections
- */
-#define _TEXT ".text"
-#define _DATA ".data"
-#define _BSS ".bss"
-#define _PAD ".pad"
-#define _LOADER ".loader"
-
-#define SCNHDR struct external_scnhdr
-#define SCNHSZ 40
-
-/* XCOFF uses a special .loader section with type STYP_LOADER. */
-#define STYP_LOADER 0x1000
-
-/* XCOFF uses a special .debug section with type STYP_DEBUG. */
-#define STYP_DEBUG 0x2000
-
-/* XCOFF handles line number or relocation overflow by creating
- another section header with STYP_OVRFLO set. */
-#define STYP_OVRFLO 0x8000
-
-/********************** LINE NUMBERS **********************/
-
-/* 1 line number entry for every "breakpointable" source line in a section.
- * Line numbers are grouped on a per function basis; first entry in a function
- * grouping will have l_lnno = 0 and in place of physical address will be the
- * symbol table index of the function name.
- */
-struct external_lineno {
- union {
- char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
- char l_paddr[4]; /* (physical) address of line number */
- } l_addr;
- char l_lnno[2]; /* line number */
-};
-
-
-#define LINENO struct external_lineno
-#define LINESZ 6
-
-
-/********************** SYMBOLS **********************/
-
-#define E_SYMNMLEN 8 /* # characters in a symbol name */
-#define E_FILNMLEN 14 /* # characters in a file name */
-#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
-
-struct external_syment
-{
- union {
- char e_name[E_SYMNMLEN];
- struct {
- char e_zeroes[4];
- char e_offset[4];
- } e;
- } e;
- char e_value[4];
- char e_scnum[2];
- char e_type[2];
- char e_sclass[1];
- char e_numaux[1];
-};
-
-
-
-#define N_BTMASK (017)
-#define N_TMASK (060)
-#define N_BTSHFT (4)
-#define N_TSHIFT (2)
-
-
-union external_auxent {
- struct {
- char x_tagndx[4]; /* str, un, or enum tag indx */
- union {
- struct {
- char x_lnno[2]; /* declaration line number */
- char x_size[2]; /* str/union/array size */
- } x_lnsz;
- char x_fsize[4]; /* size of function */
- } x_misc;
- union {
- struct { /* if ISFCN, tag, or .bb */
- char x_lnnoptr[4]; /* ptr to fcn line # */
- char x_endndx[4]; /* entry ndx past block end */
- } x_fcn;
- struct { /* if ISARY, up to 4 dimen. */
- char x_dimen[E_DIMNUM][2];
- } x_ary;
- } x_fcnary;
- char x_tvndx[2]; /* tv index */
- } x_sym;
-
- union {
- char x_fname[E_FILNMLEN];
- struct {
- char x_zeroes[4];
- char x_offset[4];
- } x_n;
- } x_file;
-
- struct {
- char x_scnlen[4]; /* section length */
- char x_nreloc[2]; /* # relocation entries */
- char x_nlinno[2]; /* # line numbers */
- } x_scn;
-
- struct {
- char x_tvfill[4]; /* tv fill value */
- char x_tvlen[2]; /* length of .tv */
- char x_tvran[2][2]; /* tv range */
- } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
-
- struct {
- unsigned char x_scnlen[4];
- unsigned char x_parmhash[4];
- unsigned char x_snhash[2];
- unsigned char x_smtyp[1];
- unsigned char x_smclas[1];
- unsigned char x_stab[4];
- unsigned char x_snstab[2];
- } x_csect;
-
-};
-
-#define SYMENT struct external_syment
-#define SYMESZ 18
-#define AUXENT union external_auxent
-#define AUXESZ 18
-#define DBXMASK 0x80 /* for dbx storage mask */
-#define SYMNAME_IN_DEBUG(symptr) ((symptr)->n_sclass & DBXMASK)
-
-
-
-/********************** RELOCATION DIRECTIVES **********************/
-
-
-struct external_reloc {
- char r_vaddr[4];
- char r_symndx[4];
- char r_size[1];
- char r_type[1];
-};
-
-
-#define RELOC struct external_reloc
-#define RELSZ 10
-
-#define DEFAULT_DATA_SECTION_ALIGNMENT 4
-#define DEFAULT_BSS_SECTION_ALIGNMENT 4
-#define DEFAULT_TEXT_SECTION_ALIGNMENT 4
-/* For new sections we havn't heard of before */
-#define DEFAULT_SECTION_ALIGNMENT 4
+++ /dev/null
-/*
- * Copyright (C) Paul Mackerras 1997.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include <stdarg.h>
-
-int (*prom)();
-
-void *chosen_handle;
-void *stdin;
-void *stdout;
-void *stderr;
-
-void exit(void);
-void *finddevice(const char *name);
-int getprop(void *phandle, const char *name, void *buf, int buflen);
-void printk(char *fmt, ...);
-
-void
-start(int a1, int a2, void *promptr)
-{
- prom = (int (*)()) promptr;
- chosen_handle = finddevice("/chosen");
- if (chosen_handle == (void *) -1)
- exit();
- if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
- exit();
- stderr = stdout;
- if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
- exit();
-
- boot(a1, a2, promptr);
- for (;;)
- exit();
-}
-
-int
-write(void *handle, void *ptr, int nb)
-{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- void *ihandle;
- void *addr;
- int len;
- int actual;
- } args;
-
- args.service = "write";
- args.nargs = 3;
- args.nret = 1;
- args.ihandle = handle;
- args.addr = ptr;
- args.len = nb;
- args.actual = -1;
- (*prom)(&args);
- return args.actual;
-}
-
-int writestring(void *f, char *ptr, int nb)
-{
- int w = 0, i;
- char *ret = "\r";
-
- for (i = 0; i < nb; ++i) {
- if (ptr[i] == '\n') {
- if (i > w) {
- write(f, ptr + w, i - w);
- w = i;
- }
- write(f, ret, 1);
- }
- }
- if (w < nb)
- write(f, ptr + w, nb - w);
- return nb;
-}
-
-int
-read(void *handle, void *ptr, int nb)
-{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- void *ihandle;
- void *addr;
- int len;
- int actual;
- } args;
-
- args.service = "read";
- args.nargs = 3;
- args.nret = 1;
- args.ihandle = handle;
- args.addr = ptr;
- args.len = nb;
- args.actual = -1;
- (*prom)(&args);
- return args.actual;
-}
-
-void
-exit()
-{
- struct prom_args {
- char *service;
- } args;
-
- for (;;) {
- args.service = "exit";
- (*prom)(&args);
- }
-}
-
-void
-pause()
-{
- struct prom_args {
- char *service;
- } args;
-
- args.service = "enter";
- (*prom)(&args);
-}
-
-void *
-finddevice(const char *name)
-{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- const char *devspec;
- void *phandle;
- } args;
-
- args.service = "finddevice";
- args.nargs = 1;
- args.nret = 1;
- args.devspec = name;
- args.phandle = (void *) -1;
- (*prom)(&args);
- return args.phandle;
-}
-
-void *
-claim(unsigned int virt, unsigned int size, unsigned int align)
-{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- unsigned int virt;
- unsigned int size;
- unsigned int align;
- void *ret;
- } args;
-
- args.service = "claim";
- args.nargs = 3;
- args.nret = 1;
- args.virt = virt;
- args.size = size;
- args.align = align;
- (*prom)(&args);
- return args.ret;
-}
-
-void
-release(void *virt, unsigned int size)
-{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- void *virt;
- unsigned int size;
- } args;
-
- args.service = "release";
- args.nargs = 2;
- args.nret = 0;
- args.virt = virt;
- args.size = size;
- (*prom)(&args);
-}
-
-int
-getprop(void *phandle, const char *name, void *buf, int buflen)
-{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- void *phandle;
- const char *name;
- void *buf;
- int buflen;
- int size;
- } args;
-
- args.service = "getprop";
- args.nargs = 4;
- args.nret = 1;
- args.phandle = phandle;
- args.name = name;
- args.buf = buf;
- args.buflen = buflen;
- args.size = -1;
- (*prom)(&args);
- return args.size;
-}
-
-int
-putc(int c, void *f)
-{
- char ch = c;
-
- return writestring(f, &ch, 1) == 1? c: -1;
-}
-
-int
-putchar(int c)
-{
- return putc(c, stdout);
-}
-
-int
-fputs(char *str, void *f)
-{
- int n = strlen(str);
-
- return writestring(f, str, n) == n? 0: -1;
-}
-
-int
-readchar()
-{
- char ch;
-
- for (;;) {
- switch (read(stdin, &ch, 1)) {
- case 1:
- return ch;
- case -1:
- printk("read(stdin) returned -1\n");
- return -1;
- }
- }
-}
-
-static char line[256];
-static char *lineptr;
-static int lineleft;
-
-int
-getchar()
-{
- int c;
-
- if (lineleft == 0) {
- lineptr = line;
- for (;;) {
- c = readchar();
- if (c == -1 || c == 4)
- break;
- if (c == '\r' || c == '\n') {
- *lineptr++ = '\n';
- putchar('\n');
- break;
- }
- switch (c) {
- case 0177:
- case '\b':
- if (lineptr > line) {
- putchar('\b');
- putchar(' ');
- putchar('\b');
- --lineptr;
- }
- break;
- case 'U' & 0x1F:
- while (lineptr > line) {
- putchar('\b');
- putchar(' ');
- putchar('\b');
- --lineptr;
- }
- break;
- default:
- if (lineptr >= &line[sizeof(line) - 1])
- putchar('\a');
- else {
- putchar(c);
- *lineptr++ = c;
- }
- }
- }
- lineleft = lineptr - line;
- lineptr = line;
- }
- if (lineleft == 0)
- return -1;
- --lineleft;
- return *lineptr++;
-}
-
-extern int vsprintf(char *buf, const char *fmt, va_list args);
-static char sprint_buf[1024];
-
-void
-printk(char *fmt, ...)
-{
- va_list args;
- int n;
-
- va_start(args, fmt);
- n = vsprintf(sprint_buf, fmt, args);
- va_end(args);
- writestring(stdout, sprint_buf, n);
-}
-
-int
-printf(char *fmt, ...)
-{
- va_list args;
- int n;
-
- va_start(args, fmt);
- n = vsprintf(sprint_buf, fmt, args);
- va_end(args);
- writestring(stdout, sprint_buf, n);
- return n;
-}
+++ /dev/null
-/*
- * String handling functions for PowerPC.
- *
- * Copyright (C) 1996 Paul Mackerras.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#define r0 0
-#define r3 3
-#define r4 4
-#define r5 5
-#define r6 6
-#define r7 7
-#define r8 8
-
- .globl strcpy
-strcpy:
- addi r5,r3,-1
- addi r4,r4,-1
-1: lbzu r0,1(r4)
- cmpwi 0,r0,0
- stbu r0,1(r5)
- bne 1b
- blr
-
- .globl strncpy
-strncpy:
- cmpwi 0,r5,0
- beqlr
- mtctr r5
- addi r6,r3,-1
- addi r4,r4,-1
-1: lbzu r0,1(r4)
- cmpwi 0,r0,0
- stbu r0,1(r6)
- bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */
- blr
-
- .globl strcat
-strcat:
- addi r5,r3,-1
- addi r4,r4,-1
-1: lbzu r0,1(r5)
- cmpwi 0,r0,0
- bne 1b
- addi r5,r5,-1
-1: lbzu r0,1(r4)
- cmpwi 0,r0,0
- stbu r0,1(r5)
- bne 1b
- blr
-
- .globl strcmp
-strcmp:
- addi r5,r3,-1
- addi r4,r4,-1
-1: lbzu r3,1(r5)
- cmpwi 1,r3,0
- lbzu r0,1(r4)
- subf. r3,r0,r3
- beqlr 1
- beq 1b
- blr
-
- .globl strlen
-strlen:
- addi r4,r3,-1
-1: lbzu r0,1(r4)
- cmpwi 0,r0,0
- bne 1b
- subf r3,r3,r4
- blr
-
- .globl memset
-memset:
- rlwimi r4,r4,8,16,23
- rlwimi r4,r4,16,0,15
- addi r6,r3,-4
- cmplwi 0,r5,4
- blt 7f
- stwu r4,4(r6)
- beqlr
- andi. r0,r6,3
- add r5,r0,r5
- subf r6,r0,r6
- rlwinm r0,r5,32-2,2,31
- mtctr r0
- bdz 6f
-1: stwu r4,4(r6)
- bdnz 1b
-6: andi. r5,r5,3
-7: cmpwi 0,r5,0
- beqlr
- mtctr r5
- addi r6,r6,3
-8: stbu r4,1(r6)
- bdnz 8b
- blr
-
- .globl bcopy
-bcopy:
- mr r6,r3
- mr r3,r4
- mr r4,r6
- b memcpy
-
- .globl memmove
-memmove:
- cmplw 0,r3,r4
- bgt backwards_memcpy
- /* fall through */
-
- .globl memcpy
-memcpy:
- rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
- addi r6,r3,-4
- addi r4,r4,-4
- beq 2f /* if less than 8 bytes to do */
- andi. r0,r6,3 /* get dest word aligned */
- mtctr r7
- bne 5f
-1: lwz r7,4(r4)
- lwzu r8,8(r4)
- stw r7,4(r6)
- stwu r8,8(r6)
- bdnz 1b
- andi. r5,r5,7
-2: cmplwi 0,r5,4
- blt 3f
- lwzu r0,4(r4)
- addi r5,r5,-4
- stwu r0,4(r6)
-3: cmpwi 0,r5,0
- beqlr
- mtctr r5
- addi r4,r4,3
- addi r6,r6,3
-4: lbzu r0,1(r4)
- stbu r0,1(r6)
- bdnz 4b
- blr
-5: subfic r0,r0,4
- mtctr r0
-6: lbz r7,4(r4)
- addi r4,r4,1
- stb r7,4(r6)
- addi r6,r6,1
- bdnz 6b
- subf r5,r0,r5
- rlwinm. r7,r5,32-3,3,31
- beq 2b
- mtctr r7
- b 1b
-
- .globl backwards_memcpy
-backwards_memcpy:
- rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
- add r6,r3,r5
- add r4,r4,r5
- beq 2f
- andi. r0,r6,3
- mtctr r7
- bne 5f
-1: lwz r7,-4(r4)
- lwzu r8,-8(r4)
- stw r7,-4(r6)
- stwu r8,-8(r6)
- bdnz 1b
- andi. r5,r5,7
-2: cmplwi 0,r5,4
- blt 3f
- lwzu r0,-4(r4)
- subi r5,r5,4
- stwu r0,-4(r6)
-3: cmpwi 0,r5,0
- beqlr
- mtctr r5
-4: lbzu r0,-1(r4)
- stbu r0,-1(r6)
- bdnz 4b
- blr
-5: mtctr r0
-6: lbzu r7,-1(r4)
- stbu r7,-1(r6)
- bdnz 6b
- subf r5,r0,r5
- rlwinm. r7,r5,32-3,3,31
- beq 2b
- mtctr r7
- b 1b
-
- .globl memcmp
-memcmp:
- cmpwi 0,r5,0
- blelr
- mtctr r5
- addi r6,r3,-1
- addi r4,r4,-1
-1: lbzu r3,1(r6)
- lbzu r0,1(r4)
- subf. r3,r0,r3
- bdnzt 2,1b
- blr
+++ /dev/null
-/*
- * This file is derived from various .h and .c files from the zlib-0.95
- * distribution by Jean-loup Gailly and Mark Adler, with some additions
- * by Paul Mackerras to aid in implementing Deflate compression and
- * decompression for PPP packets. See zlib.h for conditions of
- * distribution and use.
- *
- * Changes that have been made include:
- * - changed functions not used outside this file to "local"
- * - added minCompression parameter to deflateInit2
- * - added Z_PACKET_FLUSH (see zlib.h for details)
- * - added inflateIncomp
- *
- * $Id: zlib.c,v 1.3 1999/05/27 22:22:54 cort Exp $
- */
-
-/*+++++*/
-/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* From: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp */
-
-#define _Z_UTIL_H
-
-#include "zlib.h"
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-#define FAR
-
-typedef unsigned char uch;
-typedef uch FAR uchf;
-typedef unsigned short ush;
-typedef ush FAR ushf;
-typedef unsigned long ulg;
-
-extern char *z_errmsg[]; /* indexed by 1-zlib_error */
-
-#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err)
-/* To be used only when the state is known to be valid */
-
-#ifndef NULL
-#define NULL ((void *) 0)
-#endif
-
- /* common constants */
-
-#define DEFLATED 8
-
-#ifndef DEF_WBITS
-# define DEF_WBITS MAX_WBITS
-#endif
-/* default windowBits for decompression. MAX_WBITS is for compression only */
-
-#if MAX_MEM_LEVEL >= 8
-# define DEF_MEM_LEVEL 8
-#else
-# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-#endif
-/* default memLevel */
-
-#define STORED_BLOCK 0
-#define STATIC_TREES 1
-#define DYN_TREES 2
-/* The three kinds of block type */
-
-#define MIN_MATCH 3
-#define MAX_MATCH 258
-/* The minimum and maximum match lengths */
-
- /* functions */
-
-#include <linux/string.h>
-#define zmemcpy memcpy
-#define zmemzero(dest, len) memset(dest, 0, len)
-
-/* Diagnostic functions */
-#ifdef DEBUG_ZLIB
-# include <stdio.h>
-# ifndef verbose
-# define verbose 0
-# endif
-# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
-# define Trace(x) fprintf x
-# define Tracev(x) {if (verbose) fprintf x ;}
-# define Tracevv(x) {if (verbose>1) fprintf x ;}
-# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
-# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
-#else
-# define Assert(cond,msg)
-# define Trace(x)
-# define Tracev(x)
-# define Tracevv(x)
-# define Tracec(c,x)
-# define Tracecv(c,x)
-#endif
-
-
-typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len));
-
-/* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */
-/* void zcfree OF((voidpf opaque, voidpf ptr)); */
-
-#define ZALLOC(strm, items, size) \
- (*((strm)->zalloc))((strm)->opaque, (items), (size))
-#define ZFREE(strm, addr, size) \
- (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size))
-#define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);}
-
-/* deflate.h -- internal compression state
- * Copyright (C) 1995 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/*+++++*/
-/* infblock.h -- header to use infblock.c
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-struct inflate_blocks_state;
-typedef struct inflate_blocks_state FAR inflate_blocks_statef;
-
-local inflate_blocks_statef * inflate_blocks_new OF((
- z_stream *z,
- check_func c, /* check function */
- uInt w)); /* window size */
-
-local int inflate_blocks OF((
- inflate_blocks_statef *,
- z_stream *,
- int)); /* initial return code */
-
-local void inflate_blocks_reset OF((
- inflate_blocks_statef *,
- z_stream *,
- uLongf *)); /* check value on output */
-
-local int inflate_blocks_free OF((
- inflate_blocks_statef *,
- z_stream *,
- uLongf *)); /* check value on output */
-
-local int inflate_addhistory OF((
- inflate_blocks_statef *,
- z_stream *));
-
-local int inflate_packet_flush OF((
- inflate_blocks_statef *));
-
-/*+++++*/
-/* inftrees.h -- header to use inftrees.c
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* Huffman code lookup table entry--this entry is four bytes for machines
- that have 16-bit pointers (e.g. PC's in the small or medium model). */
-
-typedef struct inflate_huft_s FAR inflate_huft;
-
-struct inflate_huft_s {
- union {
- struct {
- Byte Exop; /* number of extra bits or operation */
- Byte Bits; /* number of bits in this code or subcode */
- } what;
- uInt Nalloc; /* number of these allocated here */
- Bytef *pad; /* pad structure to a power of 2 (4 bytes for */
- } word; /* 16-bit, 8 bytes for 32-bit machines) */
- union {
- uInt Base; /* literal, length base, or distance base */
- inflate_huft *Next; /* pointer to next level of table */
- } more;
-};
-
-#ifdef DEBUG_ZLIB
- local uInt inflate_hufts;
-#endif
-
-local int inflate_trees_bits OF((
- uIntf *, /* 19 code lengths */
- uIntf *, /* bits tree desired/actual depth */
- inflate_huft * FAR *, /* bits tree result */
- z_stream *)); /* for zalloc, zfree functions */
-
-local int inflate_trees_dynamic OF((
- uInt, /* number of literal/length codes */
- uInt, /* number of distance codes */
- uIntf *, /* that many (total) code lengths */
- uIntf *, /* literal desired/actual bit depth */
- uIntf *, /* distance desired/actual bit depth */
- inflate_huft * FAR *, /* literal/length tree result */
- inflate_huft * FAR *, /* distance tree result */
- z_stream *)); /* for zalloc, zfree functions */
-
-local int inflate_trees_fixed OF((
- uIntf *, /* literal desired/actual bit depth */
- uIntf *, /* distance desired/actual bit depth */
- inflate_huft * FAR *, /* literal/length tree result */
- inflate_huft * FAR *)); /* distance tree result */
-
-local int inflate_trees_free OF((
- inflate_huft *, /* tables to free */
- z_stream *)); /* for zfree function */
-
-
-/*+++++*/
-/* infcodes.h -- header to use infcodes.c
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-struct inflate_codes_state;
-typedef struct inflate_codes_state FAR inflate_codes_statef;
-
-local inflate_codes_statef *inflate_codes_new OF((
- uInt, uInt,
- inflate_huft *, inflate_huft *,
- z_stream *));
-
-local int inflate_codes OF((
- inflate_blocks_statef *,
- z_stream *,
- int));
-
-local void inflate_codes_free OF((
- inflate_codes_statef *,
- z_stream *));
-
-
-/*+++++*/
-/* inflate.c -- zlib interface to inflate modules
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* inflate private state */
-struct internal_state {
-
- /* mode */
- enum {
- METHOD, /* waiting for method byte */
- FLAG, /* waiting for flag byte */
- BLOCKS, /* decompressing blocks */
- CHECK4, /* four check bytes to go */
- CHECK3, /* three check bytes to go */
- CHECK2, /* two check bytes to go */
- CHECK1, /* one check byte to go */
- DONE, /* finished check, done */
- BAD} /* got an error--stay here */
- mode; /* current inflate mode */
-
- /* mode dependent information */
- union {
- uInt method; /* if FLAGS, method byte */
- struct {
- uLong was; /* computed check value */
- uLong need; /* stream check value */
- } check; /* if CHECK, check values to compare */
- uInt marker; /* if BAD, inflateSync's marker bytes count */
- } sub; /* submode */
-
- /* mode independent information */
- int nowrap; /* flag for no wrapper */
- uInt wbits; /* log2(window size) (8..15, defaults to 15) */
- inflate_blocks_statef
- *blocks; /* current inflate_blocks state */
-
-};
-
-
-int inflateReset(z)
-z_stream *z;
-{
- uLong c;
-
- if (z == Z_NULL || z->state == Z_NULL)
- return Z_STREAM_ERROR;
- z->total_in = z->total_out = 0;
- z->msg = Z_NULL;
- z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
- inflate_blocks_reset(z->state->blocks, z, &c);
- Trace((stderr, "inflate: reset\n"));
- return Z_OK;
-}
-
-
-int inflateEnd(z)
-z_stream *z;
-{
- uLong c;
-
- if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
- return Z_STREAM_ERROR;
- if (z->state->blocks != Z_NULL)
- inflate_blocks_free(z->state->blocks, z, &c);
- ZFREE(z, z->state, sizeof(struct internal_state));
- z->state = Z_NULL;
- Trace((stderr, "inflate: end\n"));
- return Z_OK;
-}
-
-
-int inflateInit2(z, w)
-z_stream *z;
-int w;
-{
- /* initialize state */
- if (z == Z_NULL)
- return Z_STREAM_ERROR;
-/* if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */
-/* if (z->zfree == Z_NULL) z->zfree = zcfree; */
- if ((z->state = (struct internal_state FAR *)
- ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
- return Z_MEM_ERROR;
- z->state->blocks = Z_NULL;
-
- /* handle undocumented nowrap option (no zlib header or check) */
- z->state->nowrap = 0;
- if (w < 0)
- {
- w = - w;
- z->state->nowrap = 1;
- }
-
- /* set window size */
- if (w < 8 || w > 15)
- {
- inflateEnd(z);
- return Z_STREAM_ERROR;
- }
- z->state->wbits = (uInt)w;
-
- /* create inflate_blocks state */
- if ((z->state->blocks =
- inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w))
- == Z_NULL)
- {
- inflateEnd(z);
- return Z_MEM_ERROR;
- }
- Trace((stderr, "inflate: allocated\n"));
-
- /* reset state */
- inflateReset(z);
- return Z_OK;
-}
-
-
-int inflateInit(z)
-z_stream *z;
-{
- return inflateInit2(z, DEF_WBITS);
-}
-
-
-#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;}
-#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
-
-int inflate(z, f)
-z_stream *z;
-int f;
-{
- int r;
- uInt b;
-
- if (z == Z_NULL || z->next_in == Z_NULL)
- return Z_STREAM_ERROR;
- r = Z_BUF_ERROR;
- while (1) switch (z->state->mode)
- {
- case METHOD:
- NEEDBYTE
- if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED)
- {
- z->state->mode = BAD;
- z->msg = "unknown compression method";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
- {
- z->state->mode = BAD;
- z->msg = "invalid window size";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- z->state->mode = FLAG;
- case FLAG:
- NEEDBYTE
- if ((b = NEXTBYTE) & 0x20)
- {
- z->state->mode = BAD;
- z->msg = "invalid reserved bit";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- if (((z->state->sub.method << 8) + b) % 31)
- {
- z->state->mode = BAD;
- z->msg = "incorrect header check";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- Trace((stderr, "inflate: zlib header ok\n"));
- z->state->mode = BLOCKS;
- case BLOCKS:
- r = inflate_blocks(z->state->blocks, z, r);
- if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0)
- r = inflate_packet_flush(z->state->blocks);
- if (r == Z_DATA_ERROR)
- {
- z->state->mode = BAD;
- z->state->sub.marker = 0; /* can try inflateSync */
- break;
- }
- if (r != Z_STREAM_END)
- return r;
- r = Z_OK;
- inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
- if (z->state->nowrap)
- {
- z->state->mode = DONE;
- break;
- }
- z->state->mode = CHECK4;
- case CHECK4:
- NEEDBYTE
- z->state->sub.check.need = (uLong)NEXTBYTE << 24;
- z->state->mode = CHECK3;
- case CHECK3:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE << 16;
- z->state->mode = CHECK2;
- case CHECK2:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE << 8;
- z->state->mode = CHECK1;
- case CHECK1:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE;
-
- if (z->state->sub.check.was != z->state->sub.check.need)
- {
- z->state->mode = BAD;
- z->msg = "incorrect data check";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- Trace((stderr, "inflate: zlib check ok\n"));
- z->state->mode = DONE;
- case DONE:
- return Z_STREAM_END;
- case BAD:
- return Z_DATA_ERROR;
- default:
- return Z_STREAM_ERROR;
- }
-
- empty:
- if (f != Z_PACKET_FLUSH)
- return r;
- z->state->mode = BAD;
- z->state->sub.marker = 0; /* can try inflateSync */
- return Z_DATA_ERROR;
-}
-
-/*
- * This subroutine adds the data at next_in/avail_in to the output history
- * without performing any output. The output buffer must be "caught up";
- * i.e. no pending output (hence s->read equals s->write), and the state must
- * be BLOCKS (i.e. we should be willing to see the start of a series of
- * BLOCKS). On exit, the output will also be caught up, and the checksum
- * will have been updated if need be.
- */
-
-int inflateIncomp(z)
-z_stream *z;
-{
- if (z->state->mode != BLOCKS)
- return Z_DATA_ERROR;
- return inflate_addhistory(z->state->blocks, z);
-}
-
-
-int inflateSync(z)
-z_stream *z;
-{
- uInt n; /* number of bytes to look at */
- Bytef *p; /* pointer to bytes */
- uInt m; /* number of marker bytes found in a row */
- uLong r, w; /* temporaries to save total_in and total_out */
-
- /* set up */
- if (z == Z_NULL || z->state == Z_NULL)
- return Z_STREAM_ERROR;
- if (z->state->mode != BAD)
- {
- z->state->mode = BAD;
- z->state->sub.marker = 0;
- }
- if ((n = z->avail_in) == 0)
- return Z_BUF_ERROR;
- p = z->next_in;
- m = z->state->sub.marker;
-
- /* search */
- while (n && m < 4)
- {
- if (*p == (Byte)(m < 2 ? 0 : 0xff))
- m++;
- else if (*p)
- m = 0;
- else
- m = 4 - m;
- p++, n--;
- }
-
- /* restore */
- z->total_in += p - z->next_in;
- z->next_in = p;
- z->avail_in = n;
- z->state->sub.marker = m;
-
- /* return no joy or set up to restart on a new block */
- if (m != 4)
- return Z_DATA_ERROR;
- r = z->total_in; w = z->total_out;
- inflateReset(z);
- z->total_in = r; z->total_out = w;
- z->state->mode = BLOCKS;
- return Z_OK;
-}
-
-#undef NEEDBYTE
-#undef NEXTBYTE
-
-/*+++++*/
-/* infutil.h -- types and macros common to blocks and codes
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* inflate blocks semi-private state */
-struct inflate_blocks_state {
-
- /* mode */
- enum {
- TYPE, /* get type bits (3, including end bit) */
- LENS, /* get lengths for stored */
- STORED, /* processing stored block */
- TABLE, /* get table lengths */
- BTREE, /* get bit lengths tree for a dynamic block */
- DTREE, /* get length, distance trees for a dynamic block */
- CODES, /* processing fixed or dynamic block */
- DRY, /* output remaining window bytes */
- DONEB, /* finished last block, done */
- BADB} /* got a data error--stuck here */
- mode; /* current inflate_block mode */
-
- /* mode dependent information */
- union {
- uInt left; /* if STORED, bytes left to copy */
- struct {
- uInt table; /* table lengths (14 bits) */
- uInt index; /* index into blens (or border) */
- uIntf *blens; /* bit lengths of codes */
- uInt bb; /* bit length tree depth */
- inflate_huft *tb; /* bit length decoding tree */
- int nblens; /* # elements allocated at blens */
- } trees; /* if DTREE, decoding info for trees */
- struct {
- inflate_huft *tl, *td; /* trees to free */
- inflate_codes_statef
- *codes;
- } decode; /* if CODES, current state */
- } sub; /* submode */
- uInt last; /* true if this block is the last block */
-
- /* mode independent information */
- uInt bitk; /* bits in bit buffer */
- uLong bitb; /* bit buffer */
- Bytef *window; /* sliding window */
- Bytef *end; /* one byte after sliding window */
- Bytef *read; /* window read pointer */
- Bytef *write; /* window write pointer */
- check_func checkfn; /* check function */
- uLong check; /* check on output */
-
-};
-
-
-/* defines for inflate input/output */
-/* update pointers and return */
-#define UPDBITS {s->bitb=b;s->bitk=k;}
-#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
-#define UPDOUT {s->write=q;}
-#define UPDATE {UPDBITS UPDIN UPDOUT}
-#define LEAVE {UPDATE return inflate_flush(s,z,r);}
-/* get bytes and bits */
-#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
-#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
-#define NEXTBYTE (n--,*p++)
-#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-#define DUMPBITS(j) {b>>=(j);k-=(j);}
-/* output bytes */
-#define WAVAIL (q<s->read?s->read-q-1:s->end-q)
-#define LOADOUT {q=s->write;m=WAVAIL;}
-#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}}
-#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
-#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
-#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
-/* load local pointers */
-#define LOAD {LOADIN LOADOUT}
-
-/*
- * The IBM 150 firmware munges the data right after _etext[]. This
- * protects it. -- Cort
- */
-local uInt protect_mask[] = {0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 ,0 ,0};
-/* And'ing with mask[n] masks the lower n bits */
-local uInt inflate_mask[] = {
- 0x0000,
- 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
- 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
-};
-
-/* copy as much as possible from the sliding window to the output area */
-local int inflate_flush OF((
- inflate_blocks_statef *,
- z_stream *,
- int));
-
-/*+++++*/
-/* inffast.h -- header to use inffast.c
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-local int inflate_fast OF((
- uInt,
- uInt,
- inflate_huft *,
- inflate_huft *,
- inflate_blocks_statef *,
- z_stream *));
-
-
-/*+++++*/
-/* infblock.c -- interpret and process block types to last block
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* Table for deflate from PKZIP's appnote.txt. */
-local uInt border[] = { /* Order of the bit length code lengths */
- 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
-/*
- Notes beyond the 1.93a appnote.txt:
-
- 1. Distance pointers never point before the beginning of the output
- stream.
- 2. Distance pointers can point back across blocks, up to 32k away.
- 3. There is an implied maximum of 7 bits for the bit length table and
- 15 bits for the actual data.
- 4. If only one code exists, then it is encoded using one bit. (Zero
- would be more efficient, but perhaps a little confusing.) If two
- codes exist, they are coded using one bit each (0 and 1).
- 5. There is no way of sending zero distance codes--a dummy must be
- sent if there are none. (History: a pre 2.0 version of PKZIP would
- store blocks with no distance codes, but this was discovered to be
- too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
- zero distance codes, which is sent as one code of zero bits in
- length.
- 6. There are up to 286 literal/length codes. Code 256 represents the
- end-of-block. Note however that the static length tree defines
- 288 codes just to fill out the Huffman codes. Codes 286 and 287
- cannot be used though, since there is no length base or extra bits
- defined for them. Similarily, there are up to 30 distance codes.
- However, static trees define 32 codes (all 5 bits) to fill out the
- Huffman codes, but the last two had better not show up in the data.
- 7. Unzip can check dynamic Huffman blocks for complete code sets.
- The exception is that a single code would not be complete (see #4).
- 8. The five bits following the block type is really the number of
- literal codes sent minus 257.
- 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
- (1+6+6). Therefore, to output three times the length, you output
- three codes (1+1+1), whereas to output four times the same length,
- you only need two codes (1+3). Hmm.
- 10. In the tree reconstruction algorithm, Code = Code + Increment
- only if BitLength(i) is not zero. (Pretty obvious.)
- 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
- 12. Note: length code 284 can represent 227-258, but length code 285
- really is 258. The last length deserves its own, short code
- since it gets used a lot in very redundant files. The length
- 258 is special since 258 - 3 (the min match length) is 255.
- 13. The literal/length and distance code bit lengths are read as a
- single stream of lengths. It is possible (and advantageous) for
- a repeat code (16, 17, or 18) to go across the boundary between
- the two sets of lengths.
- */
-
-
-local void inflate_blocks_reset(s, z, c)
-inflate_blocks_statef *s;
-z_stream *z;
-uLongf *c;
-{
- if (s->checkfn != Z_NULL)
- *c = s->check;
- if (s->mode == BTREE || s->mode == DTREE)
- ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
- if (s->mode == CODES)
- {
- inflate_codes_free(s->sub.decode.codes, z);
- inflate_trees_free(s->sub.decode.td, z);
- inflate_trees_free(s->sub.decode.tl, z);
- }
- s->mode = TYPE;
- s->bitk = 0;
- s->bitb = 0;
- s->read = s->write = s->window;
- if (s->checkfn != Z_NULL)
- s->check = (*s->checkfn)(0L, Z_NULL, 0);
- Trace((stderr, "inflate: blocks reset\n"));
-}
-
-
-local inflate_blocks_statef *inflate_blocks_new(z, c, w)
-z_stream *z;
-check_func c;
-uInt w;
-{
- inflate_blocks_statef *s;
-
- if ((s = (inflate_blocks_statef *)ZALLOC
- (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
- return s;
- if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
- {
- ZFREE(z, s, sizeof(struct inflate_blocks_state));
- return Z_NULL;
- }
- s->end = s->window + w;
- s->checkfn = c;
- s->mode = TYPE;
- Trace((stderr, "inflate: blocks allocated\n"));
- inflate_blocks_reset(s, z, &s->check);
- return s;
-}
-
-
-local int inflate_blocks(s, z, r)
-inflate_blocks_statef *s;
-z_stream *z;
-int r;
-{
- uInt t; /* temporary storage */
- uLong b; /* bit buffer */
- uInt k; /* bits in bit buffer */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
-
- /* copy input/output information to locals (UPDATE macro restores) */
- LOAD
-
- /* process input based on current state */
- while (1) switch (s->mode)
- {
- case TYPE:
- NEEDBITS(3)
- t = (uInt)b & 7;
- s->last = t & 1;
- switch (t >> 1)
- {
- case 0: /* stored */
- Trace((stderr, "inflate: stored block%s\n",
- s->last ? " (last)" : ""));
- DUMPBITS(3)
- t = k & 7; /* go to byte boundary */
- DUMPBITS(t)
- s->mode = LENS; /* get length of stored block */
- break;
- case 1: /* fixed */
- Trace((stderr, "inflate: fixed codes block%s\n",
- s->last ? " (last)" : ""));
- {
- uInt bl, bd;
- inflate_huft *tl, *td;
-
- inflate_trees_fixed(&bl, &bd, &tl, &td);
- s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
- if (s->sub.decode.codes == Z_NULL)
- {
- r = Z_MEM_ERROR;
- LEAVE
- }
- s->sub.decode.tl = Z_NULL; /* don't try to free these */
- s->sub.decode.td = Z_NULL;
- }
- DUMPBITS(3)
- s->mode = CODES;
- break;
- case 2: /* dynamic */
- Trace((stderr, "inflate: dynamic codes block%s\n",
- s->last ? " (last)" : ""));
- DUMPBITS(3)
- s->mode = TABLE;
- break;
- case 3: /* illegal */
- DUMPBITS(3)
- s->mode = BADB;
- z->msg = "invalid block type";
- r = Z_DATA_ERROR;
- LEAVE
- }
- break;
- case LENS:
- NEEDBITS(32)
- if (((~b) >> 16) != (b & 0xffff))
- {
- s->mode = BADB;
- z->msg = "invalid stored block lengths";
- r = Z_DATA_ERROR;
- LEAVE
- }
- s->sub.left = (uInt)b & 0xffff;
- b = k = 0; /* dump bits */
- Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
- s->mode = s->sub.left ? STORED : TYPE;
- break;
- case STORED:
- if (n == 0)
- LEAVE
- NEEDOUT
- t = s->sub.left;
- if (t > n) t = n;
- if (t > m) t = m;
- zmemcpy(q, p, t);
- p += t; n -= t;
- q += t; m -= t;
- if ((s->sub.left -= t) != 0)
- break;
- Tracev((stderr, "inflate: stored end, %lu total out\n",
- z->total_out + (q >= s->read ? q - s->read :
- (s->end - s->read) + (q - s->window))));
- s->mode = s->last ? DRY : TYPE;
- break;
- case TABLE:
- NEEDBITS(14)
- s->sub.trees.table = t = (uInt)b & 0x3fff;
-#ifndef PKZIP_BUG_WORKAROUND
- if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
- {
- s->mode = BADB;
- z->msg = "too many length or distance symbols";
- r = Z_DATA_ERROR;
- LEAVE
- }
-#endif
- t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
- if (t < 19)
- t = 19;
- if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
- {
- r = Z_MEM_ERROR;
- LEAVE
- }
- s->sub.trees.nblens = t;
- DUMPBITS(14)
- s->sub.trees.index = 0;
- Tracev((stderr, "inflate: table sizes ok\n"));
- s->mode = BTREE;
- case BTREE:
- while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
- {
- NEEDBITS(3)
- s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
- DUMPBITS(3)
- }
- while (s->sub.trees.index < 19)
- s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
- s->sub.trees.bb = 7;
- t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
- &s->sub.trees.tb, z);
- if (t != Z_OK)
- {
- r = t;
- if (r == Z_DATA_ERROR)
- s->mode = BADB;
- LEAVE
- }
- s->sub.trees.index = 0;
- Tracev((stderr, "inflate: bits tree ok\n"));
- s->mode = DTREE;
- case DTREE:
- while (t = s->sub.trees.table,
- s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
- {
- inflate_huft *h;
- uInt i, j, c;
-
- t = s->sub.trees.bb;
- NEEDBITS(t)
- h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
- t = h->word.what.Bits;
- c = h->more.Base;
- if (c < 16)
- {
- DUMPBITS(t)
- s->sub.trees.blens[s->sub.trees.index++] = c;
- }
- else /* c == 16..18 */
- {
- i = c == 18 ? 7 : c - 14;
- j = c == 18 ? 11 : 3;
- NEEDBITS(t + i)
- DUMPBITS(t)
- j += (uInt)b & inflate_mask[i];
- DUMPBITS(i)
- i = s->sub.trees.index;
- t = s->sub.trees.table;
- if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
- (c == 16 && i < 1))
- {
- s->mode = BADB;
- z->msg = "invalid bit length repeat";
- r = Z_DATA_ERROR;
- LEAVE
- }
- c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
- do {
- s->sub.trees.blens[i++] = c;
- } while (--j);
- s->sub.trees.index = i;
- }
- }
- inflate_trees_free(s->sub.trees.tb, z);
- s->sub.trees.tb = Z_NULL;
- {
- uInt bl, bd;
- inflate_huft *tl, *td;
- inflate_codes_statef *c;
-
- bl = 9; /* must be <= 9 for lookahead assumptions */
- bd = 6; /* must be <= 9 for lookahead assumptions */
- t = s->sub.trees.table;
- t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
- s->sub.trees.blens, &bl, &bd, &tl, &td, z);
- if (t != Z_OK)
- {
- if (t == (uInt)Z_DATA_ERROR)
- s->mode = BADB;
- r = t;
- LEAVE
- }
- Tracev((stderr, "inflate: trees ok\n"));
- if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
- {
- inflate_trees_free(td, z);
- inflate_trees_free(tl, z);
- r = Z_MEM_ERROR;
- LEAVE
- }
- ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
- s->sub.decode.codes = c;
- s->sub.decode.tl = tl;
- s->sub.decode.td = td;
- }
- s->mode = CODES;
- case CODES:
- UPDATE
- if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
- return inflate_flush(s, z, r);
- r = Z_OK;
- inflate_codes_free(s->sub.decode.codes, z);
- inflate_trees_free(s->sub.decode.td, z);
- inflate_trees_free(s->sub.decode.tl, z);
- LOAD
- Tracev((stderr, "inflate: codes end, %lu total out\n",
- z->total_out + (q >= s->read ? q - s->read :
- (s->end - s->read) + (q - s->window))));
- if (!s->last)
- {
- s->mode = TYPE;
- break;
- }
- if (k > 7) /* return unused byte, if any */
- {
- Assert(k < 16, "inflate_codes grabbed too many bytes")
- k -= 8;
- n++;
- p--; /* can always return one */
- }
- s->mode = DRY;
- case DRY:
- FLUSH
- if (s->read != s->write)
- LEAVE
- s->mode = DONEB;
- case DONEB:
- r = Z_STREAM_END;
- LEAVE
- case BADB:
- r = Z_DATA_ERROR;
- LEAVE
- default:
- r = Z_STREAM_ERROR;
- LEAVE
- }
-}
-
-
-local int inflate_blocks_free(s, z, c)
-inflate_blocks_statef *s;
-z_stream *z;
-uLongf *c;
-{
- inflate_blocks_reset(s, z, c);
- ZFREE(z, s->window, s->end - s->window);
- ZFREE(z, s, sizeof(struct inflate_blocks_state));
- Trace((stderr, "inflate: blocks freed\n"));
- return Z_OK;
-}
-
-/*
- * This subroutine adds the data at next_in/avail_in to the output history
- * without performing any output. The output buffer must be "caught up";
- * i.e. no pending output (hence s->read equals s->write), and the state must
- * be BLOCKS (i.e. we should be willing to see the start of a series of
- * BLOCKS). On exit, the output will also be caught up, and the checksum
- * will have been updated if need be.
- */
-local int inflate_addhistory(s, z)
-inflate_blocks_statef *s;
-z_stream *z;
-{
- uLong b; /* bit buffer */ /* NOT USED HERE */
- uInt k; /* bits in bit buffer */ /* NOT USED HERE */
- uInt t; /* temporary storage */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
-
- if (s->read != s->write)
- return Z_STREAM_ERROR;
- if (s->mode != TYPE)
- return Z_DATA_ERROR;
-
- /* we're ready to rock */
- LOAD
- /* while there is input ready, copy to output buffer, moving
- * pointers as needed.
- */
- while (n) {
- t = n; /* how many to do */
- /* is there room until end of buffer? */
- if (t > m) t = m;
- /* update check information */
- if (s->checkfn != Z_NULL)
- s->check = (*s->checkfn)(s->check, q, t);
- zmemcpy(q, p, t);
- q += t;
- p += t;
- n -= t;
- z->total_out += t;
- s->read = q; /* drag read pointer forward */
-/* WRAP */ /* expand WRAP macro by hand to handle s->read */
- if (q == s->end) {
- s->read = q = s->window;
- m = WAVAIL;
- }
- }
- UPDATE
- return Z_OK;
-}
-
-
-/*
- * At the end of a Deflate-compressed PPP packet, we expect to have seen
- * a `stored' block type value but not the (zero) length bytes.
- */
-local int inflate_packet_flush(s)
- inflate_blocks_statef *s;
-{
- if (s->mode != LENS)
- return Z_DATA_ERROR;
- s->mode = TYPE;
- return Z_OK;
-}
-
-
-/*+++++*/
-/* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* simplify the use of the inflate_huft type with some defines */
-#define base more.Base
-#define next more.Next
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-
-local int huft_build OF((
- uIntf *, /* code lengths in bits */
- uInt, /* number of codes */
- uInt, /* number of "simple" codes */
- uIntf *, /* list of base values for non-simple codes */
- uIntf *, /* list of extra bits for non-simple codes */
- inflate_huft * FAR*,/* result: starting table */
- uIntf *, /* maximum lookup bits (returns actual) */
- z_stream *)); /* for zalloc function */
-
-local voidpf falloc OF((
- voidpf, /* opaque pointer (not used) */
- uInt, /* number of items */
- uInt)); /* size of item */
-
-local void ffree OF((
- voidpf q, /* opaque pointer (not used) */
- voidpf p, /* what to free (not used) */
- uInt n)); /* number of bytes (not used) */
-
-/* Tables for deflate from PKZIP's appnote.txt. */
-local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
- 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
- /* actually lengths - 2; also see note #13 above about 258 */
-local uInt cplext[] = { /* Extra bits for literal codes 257..285 */
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
- 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */
-local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */
- 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
- 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
- 8193, 12289, 16385, 24577};
-local uInt cpdext[] = { /* Extra bits for distance codes */
- 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
- 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
- 12, 12, 13, 13};
-
-/*
- Huffman code decoding is performed using a multi-level table lookup.
- The fastest way to decode is to simply build a lookup table whose
- size is determined by the longest code. However, the time it takes
- to build this table can also be a factor if the data being decoded
- is not very long. The most common codes are necessarily the
- shortest codes, so those codes dominate the decoding time, and hence
- the speed. The idea is you can have a shorter table that decodes the
- shorter, more probable codes, and then point to subsidiary tables for
- the longer codes. The time it costs to decode the longer codes is
- then traded against the time it takes to make longer tables.
-
- This results of this trade are in the variables lbits and dbits
- below. lbits is the number of bits the first level table for literal/
- length codes can decode in one step, and dbits is the same thing for
- the distance codes. Subsequent tables are also less than or equal to
- those sizes. These values may be adjusted either when all of the
- codes are shorter than that, in which case the longest code length in
- bits is used, or when the shortest code is *longer* than the requested
- table size, in which case the length of the shortest code in bits is
- used.
-
- There are two different values for the two tables, since they code a
- different number of possibilities each. The literal/length table
- codes 286 possible values, or in a flat code, a little over eight
- bits. The distance table codes 30 possible values, or a little less
- than five bits, flat. The optimum values for speed end up being
- about one bit more than those, so lbits is 8+1 and dbits is 5+1.
- The optimum values may differ though from machine to machine, and
- possibly even between compilers. Your mileage may vary.
- */
-
-
-/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
-#define BMAX 15 /* maximum bit length of any code */
-#define N_MAX 288 /* maximum number of codes in any set */
-
-#ifdef DEBUG_ZLIB
- uInt inflate_hufts;
-#endif
-
-local int huft_build(b, n, s, d, e, t, m, zs)
-uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
-uInt n; /* number of codes (assumed <= N_MAX) */
-uInt s; /* number of simple-valued codes (0..s-1) */
-uIntf *d; /* list of base values for non-simple codes */
-uIntf *e; /* list of extra bits for non-simple codes */
-inflate_huft * FAR *t; /* result: starting table */
-uIntf *m; /* maximum lookup bits, returns actual */
-z_stream *zs; /* for zalloc function */
-/* Given a list of code lengths and a maximum table size, make a set of
- tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
- if the given code set is incomplete (the tables are still built in this
- case), Z_DATA_ERROR if the input is invalid (all zero length codes or an
- over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */
-{
-
- uInt a; /* counter for codes of length k */
- uInt c[BMAX+1]; /* bit length count table */
- uInt f; /* i repeats in table every f entries */
- int g; /* maximum code length */
- int h; /* table level */
- register uInt i; /* counter, current code */
- register uInt j; /* counter */
- register int k; /* number of bits in current code */
- int l; /* bits per table (returned in m) */
- register uIntf *p; /* pointer into c[], b[], or v[] */
- inflate_huft *q; /* points to current table */
- struct inflate_huft_s r; /* table entry for structure assignment */
- inflate_huft *u[BMAX]; /* table stack */
- uInt v[N_MAX]; /* values in order of bit length */
- register int w; /* bits before this table == (l * h) */
- uInt x[BMAX+1]; /* bit offsets, then code stack */
- uIntf *xp; /* pointer into x */
- int y; /* number of dummy codes added */
- uInt z; /* number of entries in current table */
-
-
- /* Generate counts for each bit length */
- p = c;
-#define C0 *p++ = 0;
-#define C2 C0 C0 C0 C0
-#define C4 C2 C2 C2 C2
- C4 /* clear c[]--assume BMAX+1 is 16 */
- p = b; i = n;
- do {
- c[*p++]++; /* assume all entries <= BMAX */
- } while (--i);
- if (c[0] == n) /* null input--all zero length codes */
- {
- *t = (inflate_huft *)Z_NULL;
- *m = 0;
- return Z_OK;
- }
-
-
- /* Find minimum and maximum length, bound *m by those */
- l = *m;
- for (j = 1; j <= BMAX; j++)
- if (c[j])
- break;
- k = j; /* minimum code length */
- if ((uInt)l < j)
- l = j;
- for (i = BMAX; i; i--)
- if (c[i])
- break;
- g = i; /* maximum code length */
- if ((uInt)l > i)
- l = i;
- *m = l;
-
-
- /* Adjust last length count to fill out codes, if needed */
- for (y = 1 << j; j < i; j++, y <<= 1)
- if ((y -= c[j]) < 0)
- return Z_DATA_ERROR;
- if ((y -= c[i]) < 0)
- return Z_DATA_ERROR;
- c[i] += y;
-
-
- /* Generate starting offsets into the value table for each length */
- x[1] = j = 0;
- p = c + 1; xp = x + 2;
- while (--i) { /* note that i == g from above */
- *xp++ = (j += *p++);
- }
-
-
- /* Make a table of values in order of bit lengths */
- p = b; i = 0;
- do {
- if ((j = *p++) != 0)
- v[x[j]++] = i;
- } while (++i < n);
-
-
- /* Generate the Huffman codes and for each, make the table entries */
- x[0] = i = 0; /* first Huffman code is zero */
- p = v; /* grab values in bit order */
- h = -1; /* no tables yet--level -1 */
- w = -l; /* bits decoded == (l * h) */
- u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
- q = (inflate_huft *)Z_NULL; /* ditto */
- z = 0; /* ditto */
-
- /* go through the bit lengths (k already is bits in shortest code) */
- for (; k <= g; k++)
- {
- a = c[k];
- while (a--)
- {
- /* here i is the Huffman code of length k bits for value *p */
- /* make tables up to required level */
- while (k > w + l)
- {
- h++;
- w += l; /* previous table always l bits */
-
- /* compute minimum size table less than or equal to l bits */
- z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */
- if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
- { /* too few codes for k-w bit table */
- f -= a + 1; /* deduct codes from patterns left */
- xp = c + k;
- if (j < z)
- while (++j < z) /* try smaller tables up to z bits */
- {
- if ((f <<= 1) <= *++xp)
- break; /* enough codes to use up j bits */
- f -= *xp; /* else deduct codes from patterns */
- }
- }
- z = 1 << j; /* table entries for j-bit table */
-
- /* allocate and link in new table */
- if ((q = (inflate_huft *)ZALLOC
- (zs,z + 1,sizeof(inflate_huft))) == Z_NULL)
- {
- if (h)
- inflate_trees_free(u[0], zs);
- return Z_MEM_ERROR; /* not enough memory */
- }
- q->word.Nalloc = z + 1;
-#ifdef DEBUG_ZLIB
- inflate_hufts += z + 1;
-#endif
- *t = q + 1; /* link to list for huft_free() */
- *(t = &(q->next)) = Z_NULL;
- u[h] = ++q; /* table starts after link */
-
- /* connect to last table, if there is one */
- if (h)
- {
- x[h] = i; /* save pattern for backing up */
- r.bits = (Byte)l; /* bits to dump before this table */
- r.exop = (Byte)j; /* bits in this table */
- r.next = q; /* pointer to this table */
- j = i >> (w - l); /* (get around Turbo C bug) */
- u[h-1][j] = r; /* connect to last table */
- }
- }
-
- /* set up table entry in r */
- r.bits = (Byte)(k - w);
- if (p >= v + n)
- r.exop = 128 + 64; /* out of values--invalid code */
- else if (*p < s)
- {
- r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
- r.base = *p++; /* simple code is just the value */
- }
- else
- {
- r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */
- r.base = d[*p++ - s];
- }
-
- /* fill code-like entries with r */
- f = 1 << (k - w);
- for (j = i >> w; j < z; j += f)
- q[j] = r;
-
- /* backwards increment the k-bit code i */
- for (j = 1 << (k - 1); i & j; j >>= 1)
- i ^= j;
- i ^= j;
-
- /* backup over finished tables */
- while ((i & ((1 << w) - 1)) != x[h])
- {
- h--; /* don't need to update q */
- w -= l;
- }
- }
- }
-
-
- /* Return Z_BUF_ERROR if we were given an incomplete table */
- return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
-}
-
-
-local int inflate_trees_bits(c, bb, tb, z)
-uIntf *c; /* 19 code lengths */
-uIntf *bb; /* bits tree desired/actual depth */
-inflate_huft * FAR *tb; /* bits tree result */
-z_stream *z; /* for zfree function */
-{
- int r;
-
- r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z);
- if (r == Z_DATA_ERROR)
- z->msg = "oversubscribed dynamic bit lengths tree";
- else if (r == Z_BUF_ERROR)
- {
- inflate_trees_free(*tb, z);
- z->msg = "incomplete dynamic bit lengths tree";
- r = Z_DATA_ERROR;
- }
- return r;
-}
-
-
-local int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z)
-uInt nl; /* number of literal/length codes */
-uInt nd; /* number of distance codes */
-uIntf *c; /* that many (total) code lengths */
-uIntf *bl; /* literal desired/actual bit depth */
-uIntf *bd; /* distance desired/actual bit depth */
-inflate_huft * FAR *tl; /* literal/length tree result */
-inflate_huft * FAR *td; /* distance tree result */
-z_stream *z; /* for zfree function */
-{
- int r;
-
- /* build literal/length tree */
- if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK)
- {
- if (r == Z_DATA_ERROR)
- z->msg = "oversubscribed literal/length tree";
- else if (r == Z_BUF_ERROR)
- {
- inflate_trees_free(*tl, z);
- z->msg = "incomplete literal/length tree";
- r = Z_DATA_ERROR;
- }
- return r;
- }
-
- /* build distance tree */
- if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK)
- {
- if (r == Z_DATA_ERROR)
- z->msg = "oversubscribed literal/length tree";
- else if (r == Z_BUF_ERROR) {
-#ifdef PKZIP_BUG_WORKAROUND
- r = Z_OK;
- }
-#else
- inflate_trees_free(*td, z);
- z->msg = "incomplete literal/length tree";
- r = Z_DATA_ERROR;
- }
- inflate_trees_free(*tl, z);
- return r;
-#endif
- }
-
- /* done */
- return Z_OK;
-}
-
-
-/* build fixed tables only once--keep them here */
-local int fixed_lock = 0;
-local int fixed_built = 0;
-#define FIXEDH 530 /* number of hufts used by fixed tables */
-local uInt fixed_left = FIXEDH;
-local inflate_huft fixed_mem[FIXEDH];
-local uInt fixed_bl;
-local uInt fixed_bd;
-local inflate_huft *fixed_tl;
-local inflate_huft *fixed_td;
-
-
-local voidpf falloc(q, n, s)
-voidpf q; /* opaque pointer (not used) */
-uInt n; /* number of items */
-uInt s; /* size of item */
-{
- Assert(s == sizeof(inflate_huft) && n <= fixed_left,
- "inflate_trees falloc overflow");
- if (q) s++; /* to make some compilers happy */
- fixed_left -= n;
- return (voidpf)(fixed_mem + fixed_left);
-}
-
-
-local void ffree(q, p, n)
-voidpf q;
-voidpf p;
-uInt n;
-{
- Assert(0, "inflate_trees ffree called!");
- if (q) q = p; /* to make some compilers happy */
-}
-
-
-local int inflate_trees_fixed(bl, bd, tl, td)
-uIntf *bl; /* literal desired/actual bit depth */
-uIntf *bd; /* distance desired/actual bit depth */
-inflate_huft * FAR *tl; /* literal/length tree result */
-inflate_huft * FAR *td; /* distance tree result */
-{
- /* build fixed tables if not built already--lock out other instances */
- while (++fixed_lock > 1)
- fixed_lock--;
- if (!fixed_built)
- {
- int k; /* temporary variable */
- unsigned c[288]; /* length list for huft_build */
- z_stream z; /* for falloc function */
-
- /* set up fake z_stream for memory routines */
- z.zalloc = falloc;
- z.zfree = ffree;
- z.opaque = Z_NULL;
-
- /* literal table */
- for (k = 0; k < 144; k++)
- c[k] = 8;
- for (; k < 256; k++)
- c[k] = 9;
- for (; k < 280; k++)
- c[k] = 7;
- for (; k < 288; k++)
- c[k] = 8;
- fixed_bl = 7;
- huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z);
-
- /* distance table */
- for (k = 0; k < 30; k++)
- c[k] = 5;
- fixed_bd = 5;
- huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z);
-
- /* done */
- fixed_built = 1;
- }
- fixed_lock--;
- *bl = fixed_bl;
- *bd = fixed_bd;
- *tl = fixed_tl;
- *td = fixed_td;
- return Z_OK;
-}
-
-
-local int inflate_trees_free(t, z)
-inflate_huft *t; /* table to free */
-z_stream *z; /* for zfree function */
-/* Free the malloc'ed tables built by huft_build(), which makes a linked
- list of the tables it made, with the links in a dummy first entry of
- each table. */
-{
- register inflate_huft *p, *q;
-
- /* Go through linked list, freeing from the malloced (t[-1]) address. */
- p = t;
- while (p != Z_NULL)
- {
- q = (--p)->next;
- ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft));
- p = q;
- }
- return Z_OK;
-}
-
-/*+++++*/
-/* infcodes.c -- process literals and length/distance pairs
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* simplify the use of the inflate_huft type with some defines */
-#define base more.Base
-#define next more.Next
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* inflate codes private state */
-struct inflate_codes_state {
-
- /* mode */
- enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
- START, /* x: set up for LEN */
- LEN, /* i: get length/literal/eob next */
- LENEXT, /* i: getting length extra (have base) */
- DIST, /* i: get distance next */
- DISTEXT, /* i: getting distance extra */
- COPY, /* o: copying bytes in window, waiting for space */
- LIT, /* o: got literal, waiting for output space */
- WASH, /* o: got eob, possibly still output waiting */
- END, /* x: got eob and all data flushed */
- BADCODE} /* x: got error */
- mode; /* current inflate_codes mode */
-
- /* mode dependent information */
- uInt len;
- union {
- struct {
- inflate_huft *tree; /* pointer into tree */
- uInt need; /* bits needed */
- } code; /* if LEN or DIST, where in tree */
- uInt lit; /* if LIT, literal */
- struct {
- uInt get; /* bits to get for extra */
- uInt dist; /* distance back to copy from */
- } copy; /* if EXT or COPY, where and how much */
- } sub; /* submode */
-
- /* mode independent information */
- Byte lbits; /* ltree bits decoded per branch */
- Byte dbits; /* dtree bits decoder per branch */
- inflate_huft *ltree; /* literal/length/eob tree */
- inflate_huft *dtree; /* distance tree */
-
-};
-
-
-local inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
-uInt bl, bd;
-inflate_huft *tl, *td;
-z_stream *z;
-{
- inflate_codes_statef *c;
-
- if ((c = (inflate_codes_statef *)
- ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
- {
- c->mode = START;
- c->lbits = (Byte)bl;
- c->dbits = (Byte)bd;
- c->ltree = tl;
- c->dtree = td;
- Tracev((stderr, "inflate: codes new\n"));
- }
- return c;
-}
-
-
-local int inflate_codes(s, z, r)
-inflate_blocks_statef *s;
-z_stream *z;
-int r;
-{
- uInt j; /* temporary storage */
- inflate_huft *t; /* temporary pointer */
- uInt e; /* extra bits or operation */
- uLong b; /* bit buffer */
- uInt k; /* bits in bit buffer */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
- Bytef *f; /* pointer to copy strings from */
- inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
-
- /* copy input/output information to locals (UPDATE macro restores) */
- LOAD
-
- /* process input and output based on current state */
- while (1) switch (c->mode)
- { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
- case START: /* x: set up for LEN */
-#ifndef SLOW
- if (m >= 258 && n >= 10)
- {
- UPDATE
- r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
- LOAD
- if (r != Z_OK)
- {
- c->mode = r == Z_STREAM_END ? WASH : BADCODE;
- break;
- }
- }
-#endif /* !SLOW */
- c->sub.code.need = c->lbits;
- c->sub.code.tree = c->ltree;
- c->mode = LEN;
- case LEN: /* i: get length/literal/eob next */
- j = c->sub.code.need;
- NEEDBITS(j)
- t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
- DUMPBITS(t->bits)
- e = (uInt)(t->exop);
- if (e == 0) /* literal */
- {
- c->sub.lit = t->base;
- Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", t->base));
- c->mode = LIT;
- break;
- }
- if (e & 16) /* length */
- {
- c->sub.copy.get = e & 15;
- c->len = t->base;
- c->mode = LENEXT;
- break;
- }
- if ((e & 64) == 0) /* next table */
- {
- c->sub.code.need = e;
- c->sub.code.tree = t->next;
- break;
- }
- if (e & 32) /* end of block */
- {
- Tracevv((stderr, "inflate: end of block\n"));
- c->mode = WASH;
- break;
- }
- c->mode = BADCODE; /* invalid code */
- z->msg = "invalid literal/length code";
- r = Z_DATA_ERROR;
- LEAVE
- case LENEXT: /* i: getting length extra (have base) */
- j = c->sub.copy.get;
- NEEDBITS(j)
- c->len += (uInt)b & inflate_mask[j];
- DUMPBITS(j)
- c->sub.code.need = c->dbits;
- c->sub.code.tree = c->dtree;
- Tracevv((stderr, "inflate: length %u\n", c->len));
- c->mode = DIST;
- case DIST: /* i: get distance next */
- j = c->sub.code.need;
- NEEDBITS(j)
- t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
- DUMPBITS(t->bits)
- e = (uInt)(t->exop);
- if (e & 16) /* distance */
- {
- c->sub.copy.get = e & 15;
- c->sub.copy.dist = t->base;
- c->mode = DISTEXT;
- break;
- }
- if ((e & 64) == 0) /* next table */
- {
- c->sub.code.need = e;
- c->sub.code.tree = t->next;
- break;
- }
- c->mode = BADCODE; /* invalid code */
- z->msg = "invalid distance code";
- r = Z_DATA_ERROR;
- LEAVE
- case DISTEXT: /* i: getting distance extra */
- j = c->sub.copy.get;
- NEEDBITS(j)
- c->sub.copy.dist += (uInt)b & inflate_mask[j];
- DUMPBITS(j)
- Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
- c->mode = COPY;
- case COPY: /* o: copying bytes in window, waiting for space */
-#ifndef __TURBOC__ /* Turbo C bug for following expression */
- f = (uInt)(q - s->window) < c->sub.copy.dist ?
- s->end - (c->sub.copy.dist - (q - s->window)) :
- q - c->sub.copy.dist;
-#else
- f = q - c->sub.copy.dist;
- if ((uInt)(q - s->window) < c->sub.copy.dist)
- f = s->end - (c->sub.copy.dist - (q - s->window));
-#endif
- while (c->len)
- {
- NEEDOUT
- OUTBYTE(*f++)
- if (f == s->end)
- f = s->window;
- c->len--;
- }
- c->mode = START;
- break;
- case LIT: /* o: got literal, waiting for output space */
- NEEDOUT
- OUTBYTE(c->sub.lit)
- c->mode = START;
- break;
- case WASH: /* o: got eob, possibly more output */
- FLUSH
- if (s->read != s->write)
- LEAVE
- c->mode = END;
- case END:
- r = Z_STREAM_END;
- LEAVE
- case BADCODE: /* x: got error */
- r = Z_DATA_ERROR;
- LEAVE
- default:
- r = Z_STREAM_ERROR;
- LEAVE
- }
-}
-
-
-local void inflate_codes_free(c, z)
-inflate_codes_statef *c;
-z_stream *z;
-{
- ZFREE(z, c, sizeof(struct inflate_codes_state));
- Tracev((stderr, "inflate: codes free\n"));
-}
-
-/*+++++*/
-/* inflate_util.c -- data and routines common to blocks and codes
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* copy as much as possible from the sliding window to the output area */
-local int inflate_flush(s, z, r)
-inflate_blocks_statef *s;
-z_stream *z;
-int r;
-{
- uInt n;
- Bytef *p, *q;
-
- /* local copies of source and destination pointers */
- p = z->next_out;
- q = s->read;
-
- /* compute number of bytes to copy as far as end of window */
- n = (uInt)((q <= s->write ? s->write : s->end) - q);
- if (n > z->avail_out) n = z->avail_out;
- if (n && r == Z_BUF_ERROR) r = Z_OK;
-
- /* update counters */
- z->avail_out -= n;
- z->total_out += n;
-
- /* update check information */
- if (s->checkfn != Z_NULL)
- s->check = (*s->checkfn)(s->check, q, n);
-
- /* copy as far as end of window */
- zmemcpy(p, q, n);
- p += n;
- q += n;
-
- /* see if more to copy at beginning of window */
- if (q == s->end)
- {
- /* wrap pointers */
- q = s->window;
- if (s->write == s->end)
- s->write = s->window;
-
- /* compute bytes to copy */
- n = (uInt)(s->write - q);
- if (n > z->avail_out) n = z->avail_out;
- if (n && r == Z_BUF_ERROR) r = Z_OK;
-
- /* update counters */
- z->avail_out -= n;
- z->total_out += n;
-
- /* update check information */
- if (s->checkfn != Z_NULL)
- s->check = (*s->checkfn)(s->check, q, n);
-
- /* copy */
- zmemcpy(p, q, n);
- p += n;
- q += n;
- }
-
- /* update pointers */
- z->next_out = p;
- s->read = q;
-
- /* done */
- return r;
-}
-
-
-/*+++++*/
-/* inffast.c -- process literals and length/distance pairs fast
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* simplify the use of the inflate_huft type with some defines */
-#define base more.Base
-#define next more.Next
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* macros for bit input with no checking and for returning unused bytes */
-#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-#define UNGRAB {n+=(c=k>>3);p-=c;k&=7;}
-
-/* Called with number of bytes left to write in window at least 258
- (the maximum string length) and number of input bytes available
- at least ten. The ten bytes are six bytes for the longest length/
- distance pair plus four bytes for overloading the bit buffer. */
-
-local int inflate_fast(bl, bd, tl, td, s, z)
-uInt bl, bd;
-inflate_huft *tl, *td;
-inflate_blocks_statef *s;
-z_stream *z;
-{
- inflate_huft *t; /* temporary pointer */
- uInt e; /* extra bits or operation */
- uLong b; /* bit buffer */
- uInt k; /* bits in bit buffer */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
- uInt ml; /* mask for literal/length tree */
- uInt md; /* mask for distance tree */
- uInt c; /* bytes to copy */
- uInt d; /* distance back to copy from */
- Bytef *r; /* copy source pointer */
-
- /* load input, output, bit values */
- LOAD
-
- /* initialize masks */
- ml = inflate_mask[bl];
- md = inflate_mask[bd];
-
- /* do until not enough input or output space for fast loop */
- do { /* assume called with m >= 258 && n >= 10 */
- /* get literal/length code */
- GRABBITS(20) /* max bits for literal/length code */
- if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
- {
- DUMPBITS(t->bits)
- Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
- "inflate: * literal '%c'\n" :
- "inflate: * literal 0x%02x\n", t->base));
- *q++ = (Byte)t->base;
- m--;
- continue;
- }
- do {
- DUMPBITS(t->bits)
- if (e & 16)
- {
- /* get extra bits for length */
- e &= 15;
- c = t->base + ((uInt)b & inflate_mask[e]);
- DUMPBITS(e)
- Tracevv((stderr, "inflate: * length %u\n", c));
-
- /* decode distance base of block to copy */
- GRABBITS(15); /* max bits for distance code */
- e = (t = td + ((uInt)b & md))->exop;
- do {
- DUMPBITS(t->bits)
- if (e & 16)
- {
- /* get extra bits to add to distance base */
- e &= 15;
- GRABBITS(e) /* get extra bits (up to 13) */
- d = t->base + ((uInt)b & inflate_mask[e]);
- DUMPBITS(e)
- Tracevv((stderr, "inflate: * distance %u\n", d));
-
- /* do the copy */
- m -= c;
- if ((uInt)(q - s->window) >= d) /* offset before dest */
- { /* just copy */
- r = q - d;
- *q++ = *r++; c--; /* minimum count is three, */
- *q++ = *r++; c--; /* so unroll loop a little */
- }
- else /* else offset after destination */
- {
- e = d - (q - s->window); /* bytes from offset to end */
- r = s->end - e; /* pointer to offset */
- if (c > e) /* if source crosses, */
- {
- c -= e; /* copy to end of window */
- do {
- *q++ = *r++;
- } while (--e);
- r = s->window; /* copy rest from start of window */
- }
- }
- do { /* copy all or what's left */
- *q++ = *r++;
- } while (--c);
- break;
- }
- else if ((e & 64) == 0)
- e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop;
- else
- {
- z->msg = "invalid distance code";
- UNGRAB
- UPDATE
- return Z_DATA_ERROR;
- }
- } while (1);
- break;
- }
- if ((e & 64) == 0)
- {
- if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0)
- {
- DUMPBITS(t->bits)
- Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
- "inflate: * literal '%c'\n" :
- "inflate: * literal 0x%02x\n", t->base));
- *q++ = (Byte)t->base;
- m--;
- break;
- }
- }
- else if (e & 32)
- {
- Tracevv((stderr, "inflate: * end of block\n"));
- UNGRAB
- UPDATE
- return Z_STREAM_END;
- }
- else
- {
- z->msg = "invalid literal/length code";
- UNGRAB
- UPDATE
- return Z_DATA_ERROR;
- }
- } while (1);
- } while (m >= 258 && n >= 10);
-
- /* not enough input or output--restore pointers and return */
- UNGRAB
- UPDATE
- return Z_OK;
-}
-
-
-/*+++++*/
-/* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */
-
-char *zlib_version = ZLIB_VERSION;
-
-char *z_errmsg[] = {
-"stream end", /* Z_STREAM_END 1 */
-"", /* Z_OK 0 */
-"file error", /* Z_ERRNO (-1) */
-"stream error", /* Z_STREAM_ERROR (-2) */
-"data error", /* Z_DATA_ERROR (-3) */
-"insufficient memory", /* Z_MEM_ERROR (-4) */
-"buffer error", /* Z_BUF_ERROR (-5) */
-""};
-
-
-/*+++++*/
-/* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */
-
-#define BASE 65521L /* largest prime smaller than 65536 */
-#define NMAX 5552
-/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-
-#define DO1(buf) {s1 += *buf++; s2 += s1;}
-#define DO2(buf) DO1(buf); DO1(buf);
-#define DO4(buf) DO2(buf); DO2(buf);
-#define DO8(buf) DO4(buf); DO4(buf);
-#define DO16(buf) DO8(buf); DO8(buf);
-
-/* ========================================================================= */
-uLong adler32(adler, buf, len)
- uLong adler;
- Bytef *buf;
- uInt len;
-{
- unsigned long s1 = adler & 0xffff;
- unsigned long s2 = (adler >> 16) & 0xffff;
- int k;
-
- if (buf == Z_NULL) return 1L;
-
- while (len > 0) {
- k = len < NMAX ? len : NMAX;
- len -= k;
- while (k >= 16) {
- DO16(buf);
- k -= 16;
- }
- if (k != 0) do {
- DO1(buf);
- } while (--k);
- s1 %= BASE;
- s2 %= BASE;
- }
- return (s2 << 16) | s1;
-}
+++ /dev/null
-/* $Id: zlib.h,v 1.1 1997/07/31 07:16:15 paulus Exp $ */
-
-/*
- * This file is derived from zlib.h and zconf.h from the zlib-0.95
- * distribution by Jean-loup Gailly and Mark Adler, with some additions
- * by Paul Mackerras to aid in implementing Deflate compression and
- * decompression for PPP packets.
- */
-
-/*
- * ==FILEVERSION 960122==
- *
- * This marker is used by the Linux installation script to determine
- * whether an up-to-date version of this file is already installed.
- */
-
-/* zlib.h -- interface of the 'zlib' general purpose compression library
- version 0.95, Aug 16th, 1995.
-
- Copyright (C) 1995 Jean-loup Gailly and Mark Adler
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jean-loup Gailly Mark Adler
- gzip@prep.ai.mit.edu madler@alumni.caltech.edu
- */
-
-#ifndef _ZLIB_H
-#define _ZLIB_H
-
-/* #include "zconf.h" */ /* included directly here */
-
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */
-
-/*
- The library does not install any signal handler. It is recommended to
- add at least a handler for SIGSEGV when decompressing; the library checks
- the consistency of the input data whenever possible but may go nuts
- for some forms of corrupted input.
- */
-
-/*
- * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
- * than 64k bytes at a time (needed on systems with 16-bit int).
- * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints
- * at addresses which are not a multiple of their size.
- * Under DOS, -DFAR=far or -DFAR=__far may be needed.
- */
-
-#ifndef STDC
-# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus)
-# define STDC
-# endif
-#endif
-
-#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */
-# include <unix.h>
-#endif
-
-/* Maximum value for memLevel in deflateInit2 */
-#ifndef MAX_MEM_LEVEL
-# ifdef MAXSEG_64K
-# define MAX_MEM_LEVEL 8
-# else
-# define MAX_MEM_LEVEL 9
-# endif
-#endif
-
-#ifndef FAR
-# define FAR
-#endif
-
-/* Maximum value for windowBits in deflateInit2 and inflateInit2 */
-#ifndef MAX_WBITS
-# define MAX_WBITS 15 /* 32K LZ77 window */
-#endif
-
-/* The memory requirements for deflate are (in bytes):
- 1 << (windowBits+2) + 1 << (memLevel+9)
- that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
- plus a few kilobytes for small objects. For example, if you want to reduce
- the default memory requirements from 256K to 128K, compile with
- make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
- Of course this will generally degrade compression (there's no free lunch).
-
- The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus a few kilobytes
- for small objects.
-*/
-
- /* Type declarations */
-
-#ifndef OF /* function prototypes */
-# ifdef STDC
-# define OF(args) args
-# else
-# define OF(args) ()
-# endif
-#endif
-
-typedef unsigned char Byte; /* 8 bits */
-typedef unsigned int uInt; /* 16 bits or more */
-typedef unsigned long uLong; /* 32 bits or more */
-
-typedef Byte FAR Bytef;
-typedef char FAR charf;
-typedef int FAR intf;
-typedef uInt FAR uIntf;
-typedef uLong FAR uLongf;
-
-#ifdef STDC
- typedef void FAR *voidpf;
- typedef void *voidp;
-#else
- typedef Byte FAR *voidpf;
- typedef Byte *voidp;
-#endif
-
-/* end of original zconf.h */
-
-#define ZLIB_VERSION "0.95P"
-
-/*
- The 'zlib' compression library provides in-memory compression and
- decompression functions, including integrity checks of the uncompressed
- data. This version of the library supports only one compression method
- (deflation) but other algorithms may be added later and will have the same
- stream interface.
-
- For compression the application must provide the output buffer and
- may optionally provide the input buffer for optimization. For decompression,
- the application must provide the input buffer and may optionally provide
- the output buffer for optimization.
-
- Compression can be done in a single step if the buffers are large
- enough (for example if an input file is mmap'ed), or can be done by
- repeated calls of the compression function. In the latter case, the
- application must provide more input and/or consume the output
- (providing more output space) before each call.
-*/
-
-typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes));
-
-struct internal_state;
-
-typedef struct z_stream_s {
- Bytef *next_in; /* next input byte */
- uInt avail_in; /* number of bytes available at next_in */
- uLong total_in; /* total nb of input bytes read so far */
-
- Bytef *next_out; /* next output byte should be put there */
- uInt avail_out; /* remaining free space at next_out */
- uLong total_out; /* total nb of bytes output so far */
-
- char *msg; /* last error message, NULL if no error */
- struct internal_state FAR *state; /* not visible by applications */
-
- alloc_func zalloc; /* used to allocate the internal state */
- free_func zfree; /* used to free the internal state */
- voidp opaque; /* private data object passed to zalloc and zfree */
-
- Byte data_type; /* best guess about the data type: ascii or binary */
-
-} z_stream;
-
-/*
- The application must update next_in and avail_in when avail_in has
- dropped to zero. It must update next_out and avail_out when avail_out
- has dropped to zero. The application must initialize zalloc, zfree and
- opaque before calling the init function. All other fields are set by the
- compression library and must not be updated by the application.
-
- The opaque value provided by the application will be passed as the first
- parameter for calls of zalloc and zfree. This can be useful for custom
- memory management. The compression library attaches no meaning to the
- opaque value.
-
- zalloc must return Z_NULL if there is not enough memory for the object.
- On 16-bit systems, the functions zalloc and zfree must be able to allocate
- exactly 65536 bytes, but will not be required to allocate more than this
- if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
- pointers returned by zalloc for objects of exactly 65536 bytes *must*
- have their offset normalized to zero. The default allocation function
- provided by this library ensures this (see zutil.c). To reduce memory
- requirements and avoid any allocation of 64K objects, at the expense of
- compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-
- The fields total_in and total_out can be used for statistics or
- progress reports. After compression, total_in holds the total size of
- the uncompressed data and may be saved for use in the decompressor
- (particularly if the decompressor wants to decompress everything in
- a single step).
-*/
-
- /* constants */
-
-#define Z_NO_FLUSH 0
-#define Z_PARTIAL_FLUSH 1
-#define Z_FULL_FLUSH 2
-#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */
-#define Z_FINISH 4
-#define Z_PACKET_FLUSH 5
-/* See deflate() below for the usage of these constants */
-
-#define Z_OK 0
-#define Z_STREAM_END 1
-#define Z_ERRNO (-1)
-#define Z_STREAM_ERROR (-2)
-#define Z_DATA_ERROR (-3)
-#define Z_MEM_ERROR (-4)
-#define Z_BUF_ERROR (-5)
-/* error codes for the compression/decompression functions */
-
-#define Z_BEST_SPEED 1
-#define Z_BEST_COMPRESSION 9
-#define Z_DEFAULT_COMPRESSION (-1)
-/* compression levels */
-
-#define Z_FILTERED 1
-#define Z_HUFFMAN_ONLY 2
-#define Z_DEFAULT_STRATEGY 0
-
-#define Z_BINARY 0
-#define Z_ASCII 1
-#define Z_UNKNOWN 2
-/* Used to set the data_type field */
-
-#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-
-extern char *zlib_version;
-/* The application can compare zlib_version and ZLIB_VERSION for consistency.
- If the first character differs, the library code actually used is
- not compatible with the zlib.h header file used by the application.
- */
-
- /* basic functions */
-
-extern int inflateInit OF((z_stream *strm));
-/*
- Initializes the internal stream state for decompression. The fields
- zalloc and zfree must be initialized before by the caller. If zalloc and
- zfree are set to Z_NULL, inflateInit updates them to use default allocation
- functions.
-
- inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory. msg is set to null if there is no error message.
- inflateInit does not perform any decompression: this will be done by
- inflate().
-*/
-
-
-extern int inflate OF((z_stream *strm, int flush));
-/*
- Performs one or both of the following actions:
-
- - Decompress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in is updated and processing
- will resume at this point for the next call of inflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. inflate() always provides as much output as possible
- (until there is no more input data or no more space in the output buffer).
-
- Before the call of inflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating the next_* and avail_* values accordingly.
- The application can consume the uncompressed output when it wants, for
- example when the output buffer is full (avail_out == 0), or after each
- call of inflate().
-
- If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH,
- inflate flushes as much output as possible to the output buffer. The
- flushing behavior of inflate is not specified for values of the flush
- parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the
- current implementation actually flushes as much output as possible
- anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data
- has been consumed, it is expecting to see the length field of a stored
- block; if not, it returns Z_DATA_ERROR.
-
- inflate() should normally be called until it returns Z_STREAM_END or an
- error. However if all decompression is to be performed in a single step
- (a single call of inflate), the parameter flush should be set to
- Z_FINISH. In this case all pending input is processed and all pending
- output is flushed; avail_out must be large enough to hold all the
- uncompressed data. (The size of the uncompressed data may have been saved
- by the compressor for this purpose.) The next operation on this stream must
- be inflateEnd to deallocate the decompression state. The use of Z_FINISH
- is never required, but can be used to inform inflate that a faster routine
- may be used for the single inflate() call.
-
- inflate() returns Z_OK if some progress has been made (more input
- processed or more output produced), Z_STREAM_END if the end of the
- compressed data has been reached and all uncompressed output has been
- produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if
- the stream structure was inconsistent (for example if next_in or next_out
- was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no
- progress is possible or if there was not enough room in the output buffer
- when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then
- call inflateSync to look for a good compression block. */
-
-
-extern int inflateEnd OF((z_stream *strm));
-/*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
-
- inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
- was inconsistent. In the error case, msg may be set but then points to a
- static string (which must not be deallocated).
-*/
-
- /* advanced functions */
-
-extern int inflateInit2 OF((z_stream *strm,
- int windowBits));
-/*
- This is another version of inflateInit with more compression options. The
- fields next_out, zalloc and zfree must be initialized before by the caller.
-
- The windowBits parameter is the base two logarithm of the maximum window
- size (the size of the history buffer). It should be in the range 8..15 for
- this version of the library (the value 16 will be allowed soon). The
- default value is 15 if inflateInit is used instead. If a compressed stream
- with a larger window size is given as input, inflate() will return with
- the error code Z_DATA_ERROR instead of trying to allocate a larger window.
-
- If next_out is not null, the library will use this buffer for the history
- buffer; the buffer must either be large enough to hold the entire output
- data, or have at least 1<<windowBits bytes. If next_out is null, the
- library will allocate its own buffer (and leave next_out null). next_in
- need not be provided here but must be provided by the application for the
- next call of inflate().
-
- If the history buffer is provided by the application, next_out must
- never be changed by the application since the decompressor maintains
- history information inside this buffer from call to call; the application
- can only reset next_out to the beginning of the history buffer when
- avail_out is zero and all output has been consumed.
-
- inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
- not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
- windowBits < 8). msg is set to null if there is no error message.
- inflateInit2 does not perform any decompression: this will be done by
- inflate().
-*/
-
-extern int inflateSync OF((z_stream *strm));
-/*
- Skips invalid compressed data until the special marker (see deflate()
- above) can be found, or until all available input is skipped. No output
- is provided.
-
- inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR
- if no more input was provided, Z_DATA_ERROR if no marker has been found,
- or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
- case, the application may save the current current value of total_in which
- indicates where valid compressed data was found. In the error case, the
- application may repeatedly call inflateSync, providing more input each time,
- until success or end of the input data.
-*/
-
-extern int inflateReset OF((z_stream *strm));
-/*
- This function is equivalent to inflateEnd followed by inflateInit,
- but does not free and reallocate all the internal decompression state.
- The stream will keep attributes that may have been set by inflateInit2.
-
- inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-extern int inflateIncomp OF((z_stream *strm));
-/*
- This function adds the data at next_in (avail_in bytes) to the output
- history without performing any output. There must be no pending output,
- and the decompressor must be expecting to see the start of a block.
- Calling this function is equivalent to decompressing a stored block
- containing the data at next_in (except that the data is not output).
-*/
-
- /* checksum functions */
-
-/*
- This function is not related to compression but is exported
- anyway because it might be useful in applications using the
- compression library.
-*/
-
-extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len));
-
-/*
- Update a running Adler-32 checksum with the bytes buf[0..len-1] and
- return the updated checksum. If buf is NULL, this function returns
- the required initial value for the checksum.
- An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
- much faster. Usage example:
-
- uLong adler = adler32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- adler = adler32(adler, buffer, length);
- }
- if (adler != original_adler) error();
-*/
-
-#ifndef _Z_UTIL_H
- struct internal_state {int dummy;}; /* hack for buggy compilers */
-#endif
-
-#endif /* _ZLIB_H */
/*
- * BK Id: SCCS/s.head.S 1.18 05/21/01 11:49:59 paulus
+ * BK Id: SCCS/s.head.S 1.21 05/23/01 00:38:42 cort
*/
/*
* PowerPC version
mr r28,r6
mr r27,r7
li r24,0 /* cpu # */
- /* N.B. prom_init clears the BSS even if it doesn't do
- * anything else -- paulus. */
- bl prom_init
+/*
+ * early_init() does the early machine identification and does
+ * the necessary low-level setup and clears the BSS
+ * -- Cort <cort@fsmlabs.com>
+ */
+ bl early_init
#ifdef CONFIG_APUS
/* On APUS the __va/__pa constants need to be set to the correct
.globl intercept_table
intercept_table:
- .long 0, i0x100, i0x200, i0x300, i0x400, 0, i0x600, i0x700
+ .long 0, 0, i0x200, i0x300, i0x400, 0, i0x600, i0x700
.long i0x800, 0, 0, 0, 0, i0xd00, 0, 0
.long 0, 0, 0, i0x1300, 0, 0, 0, 0
.long 0, 0, 0, 0, 0, 0, 0, 0
/*
- * BK Id: SCCS/s.prom.c 1.17 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.prom.c 1.20 05/23/01 00:38:42 cort
*/
/*
* Procedures for interfacing to the Open Firmware PROM on
#include <asm/mmu.h>
#include <asm/pgtable.h>
#include <asm/bitops.h>
-/* for openpic_to_irq */
+#include <asm/bootinfo.h>
#include "open_pic.h"
#ifdef CONFIG_FB
#endif
unsigned long dev_tree_size;
-/*
- * prom_init() is called very early on, before the kernel text
- * and data have been mapped to KERNELBASE. At this point the code
- * is running at whatever address it has been loaded at, so
- * references to extern and static variables must be relocated
- * explicitly. The procedure reloc_offset() returns the address
- * we're currently running at minus the address we were linked at.
- * (Note that strings count as static variables.)
- *
- * Because OF may have mapped I/O devices into the area starting at
- * KERNELBASE, particularly on CHRP machines, we can't safely call
- * OF once the kernel has been mapped to KERNELBASE. Therefore all
- * OF calls should be done within prom_init(), and prom_init()
- * and all routines called within it must be careful to relocate
- * references as necessary.
- */
-#define PTRRELOC(x) ((typeof(x))((unsigned long)(x) + offset))
-#define PTRUNRELOC(x) ((typeof(x))((unsigned long)(x) - offset))
-#define RELOC(x) (*PTRRELOC(&(x)))
-
#define ALIGN(x) (((x) + sizeof(unsigned long)-1) & -sizeof(unsigned long))
/* Is boot-info compatible ? */
char *p, *d;
int prom_version = 0;
unsigned long phys;
- extern char __bss_start, _end;
-
- /* First zero the BSS -- use memset, some arches don't have
- * caches on yet */
- memset_io(PTRRELOC(&__bss_start),0 , &_end - &__bss_start);
/* Default */
phys = offset + KERNELBASE;
- /* check if we're apus, return if we are */
- if ( r3 == 0x61707573 )
- return phys;
-
- /* If we came here from BootX, clear the screen,
- * set up some pointers and return. */
- if (r3 == 0x426f6f58 && pp == NULL) {
- bootx_init(r4, phys);
- return phys;
- }
-
- /* check if we're prep, return if we are */
- if ( *(unsigned long *)(0) == 0xdeadc0de )
- return phys;
-
/* First get a handle for the stdout device */
RELOC(prom) = pp;
RELOC(prom_chosen) = call_prom(RELOC("finddevice"), 1, 1,
/*
- * BK Id: SCCS/s.setup.c 1.23 05/21/01 16:08:53 cort
+ * BK Id: SCCS/s.setup.c 1.32 05/23/01 00:38:42 cort
*/
/*
* Common prep/pmac/chrp boot and setup code.
unsigned long r6,
unsigned long r7);
+
+extern void bootx_init(unsigned long r4, unsigned long phys);
+extern unsigned long reloc_offset(void);
+
#ifdef CONFIG_XMON
extern void xmon_map_scc(void);
#endif
}
#endif /* CONFIG_ALL_PPC */
+#ifdef CONFIG_6xx
+/*
+ * We're called here very early in the boot. We determine the machine
+ * type and call the appropriate low-level setup functions.
+ * -- Cort <cort@fsmlabs.com>
+ */
+__init
+unsigned long
+early_init(int r3, int r4, int r5)
+{
+ extern char __bss_start, _end;
+ unsigned long phys;
+ unsigned long offset = reloc_offset();
+ unsigned long local_have_of = 1, local_machine;
+ struct bi_record *rec;
+
+ /* Default */
+ phys = offset + KERNELBASE;
+
+#if defined(CONFIG_APUS)
+ return phys;
+#endif
+
+ /* First zero the BSS -- use memset, some arches don't have
+ * caches on yet */
+ memset_io(PTRRELOC(&__bss_start),0 , &_end - &__bss_start);
+
+#if defined(CONFIG_ALL_PPC) || defined(CONFIG_GEMINI)
+ /* If we came here from BootX, clear the screen,
+ * set up some pointers and return. */
+#if defined(CONFIG_ALL_PPC)
+ if ((r3 == 0x426f6f58) && (r5 == 0)) {
+ bootx_init(r4, phys);
+ return phys;
+ }
+#endif
+
+ /* check if we're prep, return if we are */
+ if ( *(unsigned long *)(0) == 0xdeadc0de )
+ return phys;
+
+ /*
+ * See if we have any bootloader info passed along. If we do,
+ * get the machine type and find out if we have OF.
+ *
+ * The strategy here is to assume that we want to call prom_init()
+ * unless the bootinfo data passed to us tell us that we don't
+ * have OF.
+ * -- Cort <cort@fsmlabs.com>
+ */
+ rec = (struct bi_record *)_ALIGN((ulong)PTRRELOC(&__bss_start)+(1<<20)-1,(1<<20));
+ if ( rec->tag == BI_FIRST )
+ {
+ for ( ; rec->tag != BI_LAST ;
+ rec = (struct bi_record *)((ulong)rec + rec->size) )
+ {
+ ulong *data = rec->data;
+ if ( rec->tag == BI_MACHTYPE )
+ {
+ local_machine = data[0];
+ local_have_of = data[1];
+ }
+ }
+ }
+
+ if ( local_have_of )
+ phys = prom_init( r3, r4, (prom_entry)r5);
+#endif
+
+ return phys;
+}
+#endif /* CONFIG_6xx */
+
/*
* Find out what kind of machine we're on and save any data we need
* from the early boot process (devtree is copied on pmac by prom_init() )
* are used for initrd_start and initrd_size,
* otherwise they contain 0xdeadbeef.
*/
- cmd_line[0] = 0;
if (r3 >= 0x4000 && r3 < 0x800000 && r4 == 0) {
strncpy(cmd_line, (char *)r3 + KERNELBASE,
sizeof(cmd_line));
chosen = find_devices("chosen");
if (chosen != NULL) {
p = get_property(chosen, "bootargs", NULL);
- if (p != NULL) {
+ if (p && *p) {
cmd_line[0] = 0;
strncpy(cmd_line, p, sizeof(cmd_line));
}
+++ /dev/null
-#
-# arch/ppc/mbxboot/Makefile
-#
-# 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) 1994 by Linus Torvalds
-# Adapted for PowerPC by Gary Thomas
-# modified by Cort (cort@cs.nmt.edu)
-#
-.c.s:
- $(CC) $(CFLAGS) -S -o $*.s $<
-.s.o:
- $(AS) -o $*.o $<
-.c.o:
- $(CC) $(CFLAGS) -DINITRD_OFFSET=$(IOFF) -DINITRD_SIZE=$(ISZ) -DZIMAGE_OFFSET=$(ZOFF) -DZIMAGE_SIZE=$(ZSZ) -c -o $*.o $<
-.S.s:
- $(CPP) $(AFLAGS) -traditional -o $*.o $<
-.S.o:
- $(CC) $(AFLAGS) -traditional -c -o $*.o $<
-
-ZOFF = 0
-ZSZ = 0
-IOFF = 0
-ISZ = 0
-
-TFTPIMAGE=/tftpboot/zImage.embedded
-
-ifdef CONFIG_8xx
-ZLINKFLAGS = -T ../vmlinux.lds -Ttext 0x00180000
-OBJECTS := head.o misc.o ../coffboot/zlib.o m8xx_tty.o
-CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS -fno-builtin -DCONFIG_8xx
-endif
-
-ifdef CONFIG_8260
-ZLINKFLAGS = -T ../vmlinux.lds -Ttext 0x00400000
-OBJECTS := head_8260.o misc.o ../coffboot/zlib.o m8260_tty.o embed_config.o
-CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS -fno-builtin -DCONFIG_8260
-endif
-
-OBJCOPY_ARGS = -O elf32-powerpc
-
-ifeq ($(CONFIG_MBX),y)
-OBJECTS += pci.o qspan_pci.o
-CFLAGS += -DCONFIG_MBX
-endif
-ifeq ($(CONFIG_RPXLITE),y)
-CFLAGS += -DCONFIG_RPXLITE
-OBJECTS += iic.o embed_config.o
-endif
-ifeq ($(CONFIG_RPXCLASSIC),y)
-CFLAGS += -DCONFIG_RPXCLASSIC
-OBJECTS += iic.o embed_config.o pci.o qspan_pci.o
-endif
-ifeq ($(CONFIG_BSEIP),y)
-CFLAGS += -DCONFIG_BSEIP
-OBJECTS += iic.o embed_config.o
-endif
-
-all: zImage
-
-zvmlinux.initrd: zvmlinux
- $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp1 $(OBJECTS)
- $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
- --add-section=initrd=ramdisk.image.gz \
- --add-section=image=../coffboot/vmlinux.gz \
- zvmlinux.initrd.tmp1 zvmlinux.initrd1
- $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd1 initrd` \
- -DINITRD_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd1 initrd` \
- -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd1 image` \
- -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd1 image` \
- -c -o misc.o misc.c
- $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS)
- $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
- --add-section=initrd=ramdisk.image.gz \
- --add-section=image=../coffboot/vmlinux.gz \
- zvmlinux.initrd.tmp $@
-
-zImage: zvmlinux
- ln -sf zvmlinux zImage
-
-zImage.initrd: zvmlinux.initrd
- ln -sf zvmlinux.initrd zImage.initrd
-
-zvmlinux: $(OBJECTS) ../coffboot/vmlinux.gz
-#
-# build the boot loader image and then compute the offset into it
-# for the kernel image
-#
- $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS)
- $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment --add-section=image=../coffboot/vmlinux.gz \
- zvmlinux.tmp $@
-#
-# then with the offset rebuild the bootloader so we know where the kernel is
-#
- $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \
- -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux image` \
- -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux image` \
- -c -o misc.o misc.c
- $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS)
- $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment --add-section=image=../coffboot/vmlinux.gz \
- zvmlinux.tmp $@
- rm zvmlinux.tmp
-
-znetboot : zImage
- cp zImage $(TFTPIMAGE)
-
-znetboot.initrd : zImage.initrd
- cp zImage.initrd $(TFTPIMAGE)
-
-clean:
- rm -f vmlinux* zvmlinux* zImage*
-
-fastdep:
- $(TOPDIR)/scripts/mkdep *.[Sch] > .depend
-
-dep:
- $(CPP) $(CPPFLAGS) -M *.S *.c > .depend
-
-# just here to match coffboot/Makefile
-vmlinux.coff:
-
-vmlinux.coff.initrd:
+++ /dev/null
-
-/* Board specific functions for those embedded 8xx boards that do
- * not have boot monitor support for board information.
- */
-#include <sys/types.h>
-#include <linux/config.h>
-#ifdef CONFIG_8xx
-#include <asm/mpc8xx.h>
-#endif
-#ifdef CONFIG_8260
-#include <asm/mpc8260.h>
-#endif
-
-
-/* IIC functions.
- * These are just the basic master read/write operations so we can
- * examine serial EEPROM.
- */
-extern void iic_read(uint devaddr, u_char *buf, uint offset, uint count);
-extern u_char aschex_to_byte(u_char *cp);
-
-/* Supply a default Ethernet address for those eval boards that don't
- * ship with one. This is an address from the MBX board I have, so
- * it is unlikely you will find it on your network.
- */
-static ushort def_enet_addr[] = { 0x0800, 0x3e26, 0x1559 };
-
-#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
-
-static void rpx_eth(bd_t *bd, u_char *cp);
-static void rpx_brate(bd_t *bd, u_char *cp);
-static void rpx_memsize(bd_t *bd, u_char *cp);
-static void rpx_cpuspeed(bd_t *bd, u_char *cp);
-
-/* Read the EEPROM on the RPX-Lite board.
-*/
-void
-rpx_cfg(bd_t *bd)
-{
- u_char eebuf[256], *cp;
-
- /* Read the first 256 bytes of the EEPROM. I think this
- * is really all there is, and I hope if it gets bigger the
- * info we want is still up front.
- */
-#if 1
- iic_read(0xa8, eebuf, 0, 128);
- iic_read(0xa8, &eebuf[128], 128, 128);
- {
- int i;
- cp = (u_char *)0xfa000000;
-
- for (i=0; i<256; i++)
- *cp++ = eebuf[i];
- }
-
- /* We look for two things, the Ethernet address and the
- * serial baud rate. The records are separated by
- * newlines.
- */
- cp = eebuf;
- for (;;) {
- if (*cp == 'E') {
- cp++;
- if (*cp == 'A') {
- cp += 2;
- rpx_eth(bd, cp);
- }
- }
- if (*cp == 'S') {
- cp++;
- if (*cp == 'B') {
- cp += 2;
- rpx_brate(bd, cp);
- }
- }
- if (*cp == 'D') {
- cp++;
- if (*cp == '1') {
- cp += 2;
- rpx_memsize(bd, cp);
- }
- }
- if (*cp == 'H') {
- cp++;
- if (*cp == 'Z') {
- cp += 2;
- rpx_cpuspeed(bd, cp);
- }
- }
-
- /* Scan to the end of the record.
- */
- while ((*cp != '\n') && (*cp != 0xff))
- cp++;
-
- /* If the next character is a 0 or ff, we are done.
- */
- cp++;
- if ((*cp == 0) || (*cp == 0xff))
- break;
- }
- bd->bi_memstart = 0;
-
-#else
- /* For boards without initialized EEPROM.
- */
- bd->bi_memstart = 0;
- bd->bi_memsize = (8 * 1024 * 1024);
- bd->bi_intfreq = 48;
- bd->bi_busfreq = 48;
- bd->bi_baudrate = 9600;
-#endif
-}
-
-static void
-rpx_eth(bd_t *bd, u_char *cp)
-{
- int i;
-
- for (i=0; i<6; i++) {
- bd->bi_enetaddr[i] = aschex_to_byte(cp);
- cp += 2;
- }
-}
-
-static void
-rpx_brate(bd_t *bd, u_char *cp)
-{
- uint rate;
-
- rate = 0;
-
- while (*cp != '\n') {
- rate *= 10;
- rate += (*cp) - '0';
- cp++;
- }
-
- bd->bi_baudrate = rate * 100;
-}
-
-static void
-rpx_memsize(bd_t *bd, u_char *cp)
-{
- uint size;
-
- size = 0;
-
- while (*cp != '\n') {
- size *= 10;
- size += (*cp) - '0';
- cp++;
- }
-
- bd->bi_memsize = size * 1024 * 1024;
-}
-
-static void
-rpx_cpuspeed(bd_t *bd, u_char *cp)
-{
- uint num, den;
-
- num = den = 0;
-
- while (*cp != '\n') {
- num *= 10;
- num += (*cp) - '0';
- cp++;
- if (*cp == '/') {
- cp++;
- den = (*cp) - '0';
- break;
- }
- }
-
- /* I don't know why the RPX just can't state the actual
- * CPU speed.....
- */
- if (den) {
- num /= den;
- num *= den;
- }
- bd->bi_intfreq = bd->bi_busfreq = num;
-
- /* The 8xx can only run a maximum 50 MHz bus speed (until
- * Motorola changes this :-). Greater than 50 MHz parts
- * run internal/2 for bus speed.
- */
- if (num > 50)
- bd->bi_busfreq /= 2;
-}
-#endif /* RPXLITE || RPXCLASSIC */
-
-#ifdef CONFIG_BSEIP
-/* Build a board information structure for the BSE ip-Engine.
- * There is more to come since we will add some environment
- * variables and a function to read them.
- */
-void
-bseip_cfg(bd_t *bd)
-{
- u_char *cp;
- int i;
-
- /* Baud rate and processor speed will eventually come
- * from the environment variables.
- */
- bd->bi_baudrate = 9600;
-
- /* Get the Ethernet station address from the Flash ROM.
- */
- cp = (u_char *)0xfe003ffa;
- for (i=0; i<6; i++) {
- bd->bi_enetaddr[i] = *cp++;
- }
-
- /* The rest of this should come from the environment as well.
- */
- bd->bi_memstart = 0;
- bd->bi_memsize = (16 * 1024 * 1024);
- bd->bi_intfreq = 48;
- bd->bi_busfreq = 48;
-}
-#endif /* BSEIP */
-
-#ifdef CONFIG_EST8260
-void
-embed_config(bd_t *bd)
-{
- u_char *cp;
- int i;
-
-#if 0
- /* This is actually provided by my boot rom. I have it
- * here for those people that may load the kernel with
- * a JTAG/COP tool and not the rom monitor.
- */
- bd->bi_baudrate = 115200;
- bd->bi_intfreq = 200;
- bd->bi_busfreq = 66;
- bd->bi_cpmfreq = 66;
- bd->bi_brgfreq = 33;
- bd->bi_memsize = 16 * 1024 * 1024;
-#endif
-
- cp = (u_char *)def_enet_addr;
- for (i=0; i<6; i++) {
- bd->bi_enetaddr[i] = *cp++;
- }
-}
-#endif /* EST8260 */
-
+++ /dev/null
-/*
- * gzimage.c
- *
- * Dummy file to allow a compressed zImage to be added
- * into a linker section, accessed by the boot coode
- */
-
-char dummy_for_gzimage;
+++ /dev/null
-#include <linux/config.h>
-#include "../kernel/ppc_defs.h"
-#include "../kernel/ppc_asm.tmpl"
-#include <asm/processor.h>
-#include <asm/cache.h>
-
- .text
-
-/*
- * $Id: head.S,v 1.6 1999/09/15 00:02:25 dmalek Exp $
- *
- * This code is loaded by the ROM loader at some arbitrary location.
- * Move it to high memory so that it can load the kernel at 0x0000.
- *
- * This is a three step process that will also work when booting from
- * a Flash PROM normally located in high memory.
- *
- * First, the entire image is loaded into some high memory address.
- * This is usually at or above 0x02000000. This is done by a network
- * boot function supported by the board or a debugger over BDM port.
- *
- * Second, the start up function here will relocate the decompress
- * function to run at the link address of 0x01000000.
- *
- * Last, the decompression function will reloate the initrd, zImage, and
- * the residual data to locations under 8 Meg. This is necessary because
- * the embedded kernel start up uses 8 Meg translations to access physical
- * space before the MMU is enabled. Finally, the zImage is uncompressed
- * to location 0 and we jump to it.
- *
- * On the MBX,
- * R1 - Stack pointer at a high memory address.
- * R3 - Pointer to Board Information Block.
- * R4 - Pointer to argument string.
- * Interrupts masked, cache and MMU disabled.
- *
- * ...and the first and second functions listed above are
- * done for us (it knows ELF images).
- *
- * For other embedded boards we build the Board Information Block.
- */
-
- .globl start
-start:
- bl start_
-start_:
-#ifndef CONFIG_MBX
- lis r11, local_bd_info@h
- ori r11, r11, local_bd_info@l
-#else
- mr r11, r3
-#endif
-
- mfmsr r3 /* Turn off interrupts */
- li r4,0
- ori r4,r4,MSR_EE
- andc r3,r3,r4
- mtmsr r3
-
-/* check if we need to relocate ourselves to the link addr or were we
- loaded there to begin with -- Cort */
- lis r4,start@h
- ori r4,r4,start@l
- mflr r3
- subi r3,r3,4 /* we get the nip, not the ip of the branch */
- mr r8,r3
-#if 0
- cmp 0,r3,r4
- beq start_ldr /* Branch if loaded OK */
-#endif
-
-/*
- * no matter where we're loaded, move ourselves to -Ttext address
- * This computes the sizes we need to determine other things.
- */
- lis r5,end@h
- ori r5,r5,end@l
- addi r5,r5,3 /* Round up - just in case */
- sub r5,r5,r4 /* Compute # longwords to move */
- srwi r5,r5,2
- mtctr r5
- mr r7,r5
- li r6,0
- subi r3,r3,4 /* Set up for loop */
- subi r4,r4,4
-00: lwzu r5,4(r3)
- stwu r5,4(r4)
- xor r6,r6,r5
- bdnz 00b
-
- lis r3,start_ldr@h
- ori r3,r3,start_ldr@l
- mtlr r3 /* Easiest way to do an absolute jump */
- blr
-
-start_ldr:
-/* Most 8xx boards don't boot up with the I-cache enabled. Do that
- * now because the decompress runs much faster that way.
- */
- lis r3, IDC_INVALL@h
- mtspr IC_CST, r3
- lis r3, IDC_ENABLE@h
- mtspr IC_CST, r3
-
-/* Clear all of BSS */
- lis r3,edata@h
- ori r3,r3,edata@l
- lis r4,end@h
- ori r4,r4,end@l
- subi r3,r3,4
- subi r4,r4,4
- li r0,0
-50: stwu r0,4(r3)
- cmp 0,r3,r4
- bne 50b
-
- lis r1,.stack@h
- ori r1,r1,.stack@l
- addi r1,r1,4096*2
- subi r1,r1,256
- li r2,0x000F /* Mask pointer to 16-byte boundary */
- andc r1,r1,r2
-
- /* Perform configuration of the various boards. This is done
- * by reading some configuration data from EEPROM and building
- * the board information structure.
- */
- mr r3, r11
- mr r21, r11
- mr r22, r8
- mr r23, r7
- mr r24, r6
-
-#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
- bl rpx_cfg
- mr r3, r21
-#endif
-#ifdef CONFIG_BSEIP
- bl bseip_cfg
- mr r3, r21
-#endif
- bl serial_init /* Init MBX serial port */
-
- mr r11, r21
- mr r8, r22
- mr r7, r23
- mr r6, r24
-
-#ifdef CONFIG_MBX
- lis r18, 0xfa200000@h /* Disable Ethernet SCC */
- li r0, 0
- stw r0, 0x0a00(r18)
-
- /* On the MBX (or anything that will TFTP load an ELF image),
- * we have to find the intermediate address. The ELF loader
- * only moves the Linux boostrap/decompress, not the zImage.
- */
-#define ILAP_ADDRESS 0xfa000020
- lis r8, ILAP_ADDRESS@h
- lwz r8, ILAP_ADDRESS@l(r8)
- addis r8, r8, 1 /* Add 64K */
-#endif
-
- mr r3,r8 /* Load point */
- mr r4,r7 /* Program length */
- mr r5,r6 /* Checksum */
- mr r6,r11 /* Residual data */
- bl decompress_kernel
-
- /* changed to use r3 (as firmware does) for kernel
- as ptr to residual -- Cort*/
- lis r6,cmd_line@h
- ori r6,r6,cmd_line@l
- lwz r6, 0(r6)
- subi r7,r6,1
-00: lbzu r2,1(r7)
- cmpi 0,r2,0
- bne 00b
-
- /* r4,r5 have initrd_start, size */
- lis r2,initrd_start@h
- ori r2,r2,initrd_start@l
- lwz r4,0(r2)
- lis r2,initrd_end@h
- ori r2,r2,initrd_end@l
- lwz r5,0(r2)
-
- /* The world starts from the beginning.
- */
- li r9,0x0
- mtlr r9
-
- /* Invalidate the instruction cache because we just copied a
- * bunch of kernel instructions.
- */
- lis r9, IDC_INVALL@h
- mtspr IC_CST, r9
-
- blr
-hang:
- b hang
-
-/*
- * Delay for a number of microseconds
- * -- Use the BUS timer (assumes 66MHz)
- */
- .globl udelay
-udelay:
- mulli r4,r3,1000 /* nanoseconds */
- addi r4,r4,59
- li r5,60
- divw r4,r4,r5 /* BUS ticks */
-1: mftbu r5
- mftb r6
- mftbu r7
- cmp 0,r5,r7
- bne 1b /* Get [synced] base time */
- addc r9,r6,r4 /* Compute end time */
- addze r8,r5
-2: mftbu r5
- cmp 0,r5,r8
- blt 2b
- bgt 3f
- mftb r6
- cmp 0,r6,r9
- blt 2b
-3: blr
-
-.globl _get_MSR
-_get_MSR:
- mfmsr r3
- blr
-
-.globl _put_MSR
-_put_MSR:
- mtmsr r3
- blr
-
- .comm .stack,4096*2,4
-#ifndef CONFIG_MBX
-local_bd_info:
- .long 0
- .long 0x01000000
- .long 64
- .long 64
- .long 0
- .long 0
- .long 0
-#endif
+++ /dev/null
-#include "../kernel/ppc_defs.h"
-#include "../kernel/ppc_asm.tmpl"
-#include <asm/processor.h>
-#include <asm/cache.h>
-
- .text
-
-/*
- * $Id: head.S,v 1.33 1999/09/08 01:06:58 cort Exp $
- *
- * Boot loader philosophy:
- *
- * ROM loads us to some arbitrary location
- * ROM loads these registers:
- *
- * R3 = Pointer to the board configuration data
- * R5 = Pointer to Open Firmware data
- *
- * ROM jumps to start/start_
- * Move the boot code to the link address (4 MB)
- * Call decompress_kernel()
- * Relocate the initrd, zimage and residual data to 4 MB
- * Decompress the kernel to 0
- * Jump to the kernel entry
- * -- Cort
- */
- .globl start
-start:
- bl start_
-start_:
- mr r11,r3 /* Save pointer to residual/board data */
- mr r25,r5 /* Save OFW pointer */
- li r3,MSR_IP /* Establish default MSR value */
- mtmsr r3
-
-/* check if we need to relocate ourselves to the link addr or were we
- loaded there to begin with -- Cort */
- lis r4,start@h
- ori r4,r4,start@l
- mflr r3
- subi r3,r3,4 /* we get the nip, not the ip of the branch */
- mr r8,r3
- cmp 0,r3,r4
- bne 1010f
-/* compute size of whole image in words. this should be moved to
- * start_ldr() -- Cort
- */
- lis r4,start@h
- ori r4,r4,start@l
- lis r5,end@h
- ori r5,r5,end@l
- addi r5,r5,3 /* round up */
- sub r5,r5,r4
- srwi r5,r5,2
- mr r7,r5
- b start_ldr
-1010:
-/*
- * no matter where we're loaded, move ourselves to -Ttext address
- */
-relocate:
- mflr r3 /* Compute code bias */
- subi r3,r3,4
- mr r8,r3
- lis r4,start@h
- ori r4,r4,start@l
- lis r5,end@h
- ori r5,r5,end@l
- addi r5,r5,3 /* Round up - just in case */
- sub r5,r5,r4 /* Compute # longwords to move */
- srwi r5,r5,2
- mtctr r5
- mr r7,r5
- li r6,0
- subi r3,r3,4 /* Set up for loop */
- subi r4,r4,4
-00: lwzu r5,4(r3)
- stwu r5,4(r4)
- xor r6,r6,r5
- bdnz 00b
- lis r3,start_ldr@h
- ori r3,r3,start_ldr@l
- mtlr r3 /* Easiest way to do an absolute jump */
- blr
-start_ldr:
-/* Clear all of BSS */
- lis r3,edata@h
- ori r3,r3,edata@l
- lis r4,end@h
- ori r4,r4,end@l
- subi r3,r3,4
- subi r4,r4,4
- li r0,0
-50: stwu r0,4(r3)
- cmp 0,r3,r4
- bne 50b
-90: mr r9,r1 /* Save old stack pointer (in case it matters) */
- lis r1,.stack@h
- ori r1,r1,.stack@l
- addi r1,r1,4096*2
- subi r1,r1,256
- li r2,0x000F /* Mask pointer to 16-byte boundary */
- andc r1,r1,r2
-
- /* Speed us up a little.
- */
- bl flush_instruction_cache
-
-/* Run loader */
- mr r3,r8 /* Load point */
- mr r4,r7 /* Program length */
- mr r5,r6 /* Checksum */
- mr r6,r11 /* Residual data */
- mr r7,r25 /* OFW interfaces */
- bl decompress_kernel
-
- /* changed to use r3 (as firmware does) for kernel
- as ptr to residual -- Cort*/
- lis r6,cmd_line@h
- ori r6,r6,cmd_line@l
- lwz r6, 0(r6)
- subi r7,r6,1
-00: lbzu r2,1(r7)
- cmpi 0,r2,0
- bne 00b
-
- /* r4,r5 have initrd_start, size */
- lis r2,initrd_start@h
- ori r2,r2,initrd_start@l
- lwz r4,0(r2)
- lis r2,initrd_end@h
- ori r2,r2,initrd_end@l
- lwz r5,0(r2)
-
- /* tell kernel we're prep */
- /*
- * get start address of kernel code which is stored as a coff
- * entry. see boot/head.S -- Cort
- */
- li r9,0x4
- mtlr r9
- lis r10,0xdeadc0de@h
- ori r10,r10,0xdeadc0de@l
- li r9,0
- stw r10,0(r9)
-/*
- * The Radstone firmware maps PCI memory at 0xc0000000 using BAT2
- * so disable BATs before setting this to avoid a clash
- */
- li r8,0
- mtspr DBAT0U,r8
- mtspr DBAT1U,r8
- mtspr DBAT2U,r8
- mtspr DBAT3U,r8
- mtspr IBAT0U,r8
- mtspr IBAT1U,r8
- mtspr IBAT2U,r8
- mtspr IBAT3U,r8
-
- blr
-hang:
- b hang
-
-/*
- * Delay for a number of microseconds
- * -- Use the BUS timer (assumes 66MHz)
- */
- .globl udelay
-udelay:
- mfspr r4,PVR
- srwi r4,r4,16
- cmpi 0,r4,1 /* 601 ? */
- bne .udelay_not_601
-00: li r0,86 /* Instructions / microsecond? */
- mtctr r0
-10: addi r0,r0,0 /* NOP */
- bdnz 10b
- subic. r3,r3,1
- bne 00b
- blr
-
-.udelay_not_601:
- mulli r4,r3,1000 /* nanoseconds */
- addi r4,r4,59
- li r5,60
- divw r4,r4,r5 /* BUS ticks */
-1: mftbu r5
- mftb r6
- mftbu r7
- cmp 0,r5,r7
- bne 1b /* Get [synced] base time */
- addc r9,r6,r4 /* Compute end time */
- addze r8,r5
-2: mftbu r5
- cmp 0,r5,r8
- blt 2b
- bgt 3f
- mftb r6
- cmp 0,r6,r9
- blt 2b
-3: blr
-
-.globl _get_HID0
-_get_HID0:
- mfspr r3,HID0
- blr
-
-.globl _put_HID0
-_put_HID0:
- mtspr HID0,r3
- blr
-
-.globl _get_MSR
-_get_MSR:
- mfmsr r3
- blr
-
-.globl _put_MSR
-_put_MSR:
- mtmsr r3
- blr
-
-/*
- * Flush instruction cache
- * *** I'm really paranoid here!
- */
-_GLOBAL(flush_instruction_cache)
- mflr r5
- bl flush_data_cache
- mfspr r3,HID0 /* Caches are controlled by this register */
- li r4,0
- ori r4,r4,(HID0_ICE|HID0_ICFI)
- or r3,r3,r4 /* Need to enable+invalidate to clear */
- mtspr HID0,r3
- andc r3,r3,r4
- ori r3,r3,HID0_ICE /* Enable cache */
- mtspr HID0,r3
- mtlr r5
- blr
-
-#define NUM_CACHE_LINES 128*8
-#define CACHE_LINE_SIZE 32
-#define cache_flush_buffer 0x1000
-
-/*
- * Flush data cache
- * *** I'm really paranoid here!
- */
-_GLOBAL(flush_data_cache)
- lis r3,cache_flush_buffer@h
- ori r3,r3,cache_flush_buffer@l
- li r4,NUM_CACHE_LINES
- mtctr r4
-00: lwz r4,0(r3)
- addi r3,r3,CACHE_LINE_SIZE /* Next line, please */
- bdnz 00b
-10: blr
- .comm .stack,4096*2,4
+++ /dev/null
-
-/* Minimal support functions to read configuration from IIC EEPROMS
- * on MPC8xx boards. Originally written for RPGC RPX-Lite.
- * Dan Malek (dmalek@jlc.net).
- */
-#include <linux/types.h>
-#include <asm/uaccess.h>
-#include "asm/mpc8xx.h"
-#include "../8xx_io/commproc.h"
-
-
-/* IIC functions.
- * These are just the basic master read/write operations so we can
- * examine serial EEPROM.
- */
-void iic_read(uint devaddr, u_char *buf, uint offset, uint count);
-u_char aschex_to_byte(u_char *cp);
-
-static int iic_init_done;
-
-static void
-iic_init()
-{
- volatile iic_t *iip;
- volatile i2c8xx_t *i2c;
- volatile cbd_t *tbdf, *rbdf;
- volatile cpm8xx_t *cp;
- volatile immap_t *immap;
- uint dpaddr;
-
- immap = (immap_t *)IMAP_ADDR;
- cp = (cpm8xx_t *)&(immap->im_cpm);
-
- /* Reset the CPM. This is necessary on the 860 processors
- * that may have started the SCC1 ethernet without relocating
- * the IIC.
- * This also stops the Ethernet in case we were loaded by a
- * BOOTP rom monitor.
- */
- cp->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG);
-
- /* Wait for it.
- */
- while (cp->cp_cpcr & (CPM_CR_RST | CPM_CR_FLG));
-
- /* Remove any microcode patches. We will install our own
- * later.
- */
- cp->cp_cpmcr1 = 0;
- cp->cp_cpmcr2 = 0;
- cp->cp_cpmcr3 = 0;
- cp->cp_cpmcr4 = 0;
- cp->cp_rccr = 0;
-
- iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
- i2c = (i2c8xx_t *)&(immap->im_i2c);
-
- /* Initialize Port B IIC pins.
- */
- cp->cp_pbpar |= 0x00000030;
- cp->cp_pbdir |= 0x00000030;
- cp->cp_pbodr |= 0x00000030;
-
- /* Initialize the parameter ram.
- */
-
- /* Allocate space for a two transmit and one receive buffer
- * descriptor in the DP ram.
- * For now, this address seems OK, but it may have to
- * change with newer versions of the firmware.
- */
- dpaddr = 0x0840;
-
- /* Set up the IIC parameters in the parameter ram.
- */
- iip->iic_tbase = dpaddr;
- iip->iic_rbase = dpaddr + (2 * sizeof(cbd_t));
-
- iip->iic_tfcr = SMC_EB;
- iip->iic_rfcr = SMC_EB;
-
- /* This should really be done by the reader/writer.
- */
- iip->iic_mrblr = 128;
-
- /* Initialize Tx/Rx parameters.
- */
- cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FLG;
- while (cp->cp_cpcr & CPM_CR_FLG);
-
- /* Select an arbitrary address. Just make sure it is unique.
- */
- i2c->i2c_i2add = 0x34;
-
- /* Make clock run maximum slow.
- */
- i2c->i2c_i2brg = 7;
-
- /* Disable interrupts.
- */
- i2c->i2c_i2cmr = 0;
- i2c->i2c_i2cer = 0xff;
-
- /* Enable SDMA.
- */
- immap->im_siu_conf.sc_sdcr = 1;
-
- iic_init_done = 1;
-}
-
-/* Read from IIC.
- * Caller provides device address, memory buffer, and byte count.
- */
-static u_char iitemp[32];
-
-void
-iic_read(uint devaddr, u_char *buf, uint offset, uint count)
-{
- volatile iic_t *iip;
- volatile i2c8xx_t *i2c;
- volatile cbd_t *tbdf, *rbdf;
- volatile cpm8xx_t *cp;
- volatile immap_t *immap;
- u_char *tb;
- uint dpaddr, temp;
-
- /* If the interface has not been initialized, do that now.
- */
- if (!iic_init_done)
- iic_init();
-
- immap = (immap_t *)IMAP_ADDR;
- cp = (cpm8xx_t *)&(immap->im_cpm);
-
- iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
- i2c = (i2c8xx_t *)&(immap->im_i2c);
-
- tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase];
- rbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_rbase];
-
- /* Send a "dummy write" operation. This is a write request with
- * only the offset sent, followed by another start condition.
- * This will ensure we start reading from the first location
- * of the EEPROM.
- */
- tb = iitemp;
- tb = (u_char *)(((uint)tb + 15) & ~15);
- tbdf->cbd_bufaddr = tb;
- *tb = devaddr & 0xfe; /* Device address */
- *(tb+1) = offset; /* Offset */
- tbdf->cbd_datlen = 2; /* Length */
- tbdf->cbd_sc =
- BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START;
-
- i2c->i2c_i2mod = 1; /* Enable */
- i2c->i2c_i2cer = 0xff;
- i2c->i2c_i2com = 0x81; /* Start master */
-
- /* Wait for IIC transfer.
- */
-#if 0
- while ((i2c->i2c_i2cer & 3) == 0);
-
- if (tbdf->cbd_sc & BD_SC_READY)
- printf("IIC ra complete but tbuf ready\n");
-#else
- temp = 10000000;
- while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0))
- temp--;
-#if 0
- /* We can't do this...there is no serial port yet!
- */
- if (temp == 0) {
- printf("Timeout reading EEPROM\n");
- return;
- }
-#endif
-#endif
-
- /* Chip errata, clear enable.
- */
- i2c->i2c_i2mod = 0;
-
- /* To read, we need an empty buffer of the proper length.
- * All that is used is the first byte for address, the remainder
- * is just used for timing (and doesn't really have to exist).
- */
- tbdf->cbd_bufaddr = tb;
- *tb = devaddr | 1; /* Device address */
- rbdf->cbd_bufaddr = (uint)buf; /* Desination buffer */
- tbdf->cbd_datlen = rbdf->cbd_datlen = count + 1; /* Length */
- tbdf->cbd_sc = BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START;
- rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
-
- /* Chip bug, set enable here.
- */
- i2c->i2c_i2mod = 1; /* Enable */
- i2c->i2c_i2cer = 0xff;
- i2c->i2c_i2com = 0x81; /* Start master */
-
- /* Wait for IIC transfer.
- */
-#if 0
- while ((i2c->i2c_i2cer & 1) == 0);
-
- if (rbdf->cbd_sc & BD_SC_EMPTY)
- printf("IIC read complete but rbuf empty\n");
-#else
- temp = 10000000;
- while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0))
- temp--;
-#endif
-
- /* Chip errata, clear enable.
- */
- i2c->i2c_i2mod = 0;
-}
-
-/* Because I didn't find anything that would do this.......
-*/
-u_char
-aschex_to_byte(u_char *cp)
-{
- u_char byte, c;
-
- c = *cp++;
-
- if ((c >= 'A') && (c <= 'F')) {
- c -= 'A';
- c += 10;
- }
- else if ((c >= 'a') && (c <= 'f')) {
- c -= 'a';
- c += 10;
- }
- else {
- c -= '0';
- }
-
- byte = c * 16;
-
- c = *cp;
-
- if ((c >= 'A') && (c <= 'F')) {
- c -= 'A';
- c += 10;
- }
- else if ((c >= 'a') && (c <= 'f')) {
- c -= 'a';
- c += 10;
- }
- else {
- c -= '0';
- }
-
- byte += c;
-
- return(byte);
-}
+++ /dev/null
-
-
-/* Minimal serial functions needed to send messages out the serial
- * port on SMC1.
- */
-#include <linux/types.h>
-#include "asm/mpc8260.h"
-#include "asm/cpm_8260.h"
-
-uint no_print;
-extern char *params[];
-extern int nparams;
-static u_char cons_hold[128], *sgptr;
-static int cons_hold_cnt;
-
-void
-serial_init(bd_t *bd)
-{
- volatile smc_t *sp;
- volatile smc_uart_t *up;
- volatile cbd_t *tbdf, *rbdf;
- volatile immap_t *ip;
- volatile iop8260_t *io;
- volatile cpm8260_t *cp;
- uint dpaddr, memaddr;
-
- ip = (immap_t *)IMAP_ADDR;
-
- sp = (smc_t*)&(ip->im_smc[0]);
- *(ushort *)(&ip->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1;
- up = (smc_uart_t *)&ip->im_dprambase[PROFF_SMC1];
-
- cp = &ip->im_cpm;
- io = &ip->im_ioport;
-
- /* Disable transmitter/receiver.
- */
- sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
-
- /* Use Port D for SMC1 instead of other functions.
- */
- io->iop_ppard |= 0x00c00000;
- io->iop_pdird |= 0x00400000;
- io->iop_pdird &= ~0x00800000;
- io->iop_psord &= ~0x00c00000;
-
- /* Allocate space for two buffer descriptors in the DP ram.
- * For now, this address seems OK, but it may have to
- * change with newer versions of the firmware.
- */
- dpaddr = 0x0800;
-
- /* Grab a few bytes from the top of memory.
- */
-#if 1
- memaddr = (bd->bi_memsize - 256) & ~15;
-#else
- memaddr = 0x0f002c00;
-#endif
-
- /* Set the physical address of the host memory buffers in
- * the buffer descriptors.
- */
- rbdf = (cbd_t *)&ip->im_dprambase[dpaddr];
- rbdf->cbd_bufaddr = memaddr;
- rbdf->cbd_sc = 0;
- tbdf = rbdf + 1;
- tbdf->cbd_bufaddr = memaddr+128;
- tbdf->cbd_sc = 0;
-
- /* Set up the uart parameters in the parameter ram.
- */
- up->smc_rbase = dpaddr;
- up->smc_tbase = dpaddr+sizeof(cbd_t);
- up->smc_rfcr = CPMFCR_EB;
- up->smc_tfcr = CPMFCR_EB;
- up->smc_brklen = 0;
- up->smc_brkec = 0;
- up->smc_brkcr = 0;
-
- /* Set UART mode, 8 bit, no parity, one stop.
- * Enable receive and transmit.
- */
- sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART;
-
- /* Mask all interrupts and remove anything pending.
- */
- sp->smc_smcm = 0;
- sp->smc_smce = 0xff;
-
- /* Set up the baud rate generator.
- */
- ip->im_clkrst.car_sccr = 0; /* DIV 4 BRG */
- ip->im_cpmux.cmx_smr = 0;
- ip->im_brgc1 =
- ((((bd->bi_brgfreq * 1000000)/16) / bd->bi_baudrate) << 1) |
- CPM_BRG_EN;
-
- /* Make the first buffer the only buffer.
- */
- tbdf->cbd_sc |= BD_SC_WRAP;
- rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
-
-#if 0
- /* Single character receive.
- */
- up->smc_mrblr = 1;
- up->smc_maxidl = 0;
-#else
- up->smc_mrblr = 128;
- up->smc_maxidl = 8;
-#endif
-
- /* Initialize Tx/Rx parameters.
- */
- cp->cp_cpcr = mk_cr_cmd(CPM_CR_SMC1_PAGE, CPM_CR_SMC1_SBLOCK, 0, CPM_CR_INIT_TRX) | CPM_CR_FLG;
- while (cp->cp_cpcr & CPM_CR_FLG);
-
- /* Enable transmitter/receiver.
- */
- sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
-}
-
-void
-serial_putchar(const char c)
-{
- volatile cbd_t *tbdf;
- volatile char *buf;
- volatile smc_uart_t *up;
- volatile immap_t *ip;
- extern bd_t *board_info;
-
- ip = (immap_t *)IMAP_ADDR;
- up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]);
- tbdf = (cbd_t *)&ip->im_dprambase[up->smc_tbase];
-
- /* Wait for last character to go.
- */
- buf = (char *)tbdf->cbd_bufaddr;
- while (tbdf->cbd_sc & BD_SC_READY);
-
- *buf = c;
- tbdf->cbd_datlen = 1;
- tbdf->cbd_sc |= BD_SC_READY;
-}
-
-char
-serial_getc()
-{
- char c;
-
- if (cons_hold_cnt <= 0) {
- cons_hold_cnt = serial_readbuf(cons_hold);
- sgptr = cons_hold;
- }
- c = *sgptr++;
- cons_hold_cnt--;
-
- return(c);
-}
-
-int
-serial_readbuf(u_char *cbuf)
-{
- volatile cbd_t *rbdf;
- volatile char *buf;
- volatile smc_uart_t *up;
- volatile immap_t *ip;
- int i, nc;
-
- ip = (immap_t *)IMAP_ADDR;
-
- up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]);
- rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase];
-
- /* Wait for character to show up.
- */
- buf = (char *)rbdf->cbd_bufaddr;
- while (rbdf->cbd_sc & BD_SC_EMPTY);
- nc = rbdf->cbd_datlen;
- for (i=0; i<nc; i++)
- *cbuf++ = *buf++;
- rbdf->cbd_sc |= BD_SC_EMPTY;
-
- return(nc);
-}
-
-int
-serial_tstc()
-{
- volatile cbd_t *rbdf;
- volatile smc_uart_t *up;
- volatile immap_t *ip;
-
- ip = (immap_t *)IMAP_ADDR;
- up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]);
- rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase];
-
- return(!(rbdf->cbd_sc & BD_SC_EMPTY));
-}
-
+++ /dev/null
-
-
-/* Minimal serial functions needed to send messages out the serial
- * port on the MBX console.
- *
- * The MBX uxes SMC1 for the serial port. We reset the port and use
- * only the first BD that EPPC-Bug set up as a character FIFO.
- *
- * Later versions (at least 1.4, maybe earlier) of the MBX EPPC-Bug
- * use COM1 instead of SMC1 as the console port. This kinda sucks
- * for the rest of the kernel, so here we force the use of SMC1 again.
- */
-#include <linux/config.h>
-#include <linux/types.h>
-#include <asm/uaccess.h>
-#include <asm/mpc8xx.h>
-#include "../8xx_io/commproc.h"
-
-#ifdef CONFIG_MBX
-#define MBX_CSR1 ((volatile u_char *)0xfa100000)
-#define CSR1_COMEN (u_char)0x02
-#endif
-
-#ifdef TQM_SMC2_CONSOLE
-#define PROFF_CONS PROFF_SMC2
-#define CPM_CR_CH_CONS CPM_CR_CH_SMC2
-#define SMC_INDEX 1
-static volatile iop8xx_t *iopp = (iop8xx_t *)&(((immap_t *)IMAP_ADDR)->im_ioport);
-#else
-#define PROFF_CONS PROFF_SMC1
-#define CPM_CR_CH_CONS CPM_CR_CH_SMC1
-#define SMC_INDEX 0
-#endif
-
-static cpm8xx_t *cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
-
-void
-serial_init(bd_t *bd)
-{
- volatile smc_t *sp;
- volatile smc_uart_t *up;
- volatile cbd_t *tbdf, *rbdf;
- volatile cpm8xx_t *cp;
- uint dpaddr, memaddr;
-
- cp = cpmp;
- sp = (smc_t*)&(cp->cp_smc[SMC_INDEX]);
- up = (smc_uart_t *)&cp->cp_dparam[PROFF_CONS];
-
- /* Disable transmitter/receiver.
- */
- sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
-
-#ifndef CONFIG_MBX
- {
- /* Initialize SMCx and use it for the console port.
- */
-
- /* Enable SDMA.
- */
- ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1;
-
-#ifdef TQM_SMC2_CONSOLE
- /* Use Port A for SMC2 instead of other functions.
- */
- iopp->iop_papar |= 0x00c0;
- iopp->iop_padir &= ~0x00c0;
- iopp->iop_paodr &= ~0x00c0;
-#else
- /* Use Port B for SMCs instead of other functions.
- */
- cp->cp_pbpar |= 0x00000cc0;
- cp->cp_pbdir &= ~0x00000cc0;
- cp->cp_pbodr &= ~0x00000cc0;
-#endif
-
- /* Allocate space for two buffer descriptors in the DP ram.
- * For now, this address seems OK, but it may have to
- * change with newer versions of the firmware.
- */
- dpaddr = 0x0800;
-
- /* Grab a few bytes from the top of memory for SMC FIFOs.
- */
- memaddr = (bd->bi_memsize - 32) & ~15;
-
- /* Set the physical address of the host memory buffers in
- * the buffer descriptors.
- */
- rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr];
- rbdf->cbd_bufaddr = memaddr;
- rbdf->cbd_sc = 0;
- tbdf = rbdf + 1;
- tbdf->cbd_bufaddr = memaddr+4;
- tbdf->cbd_sc = 0;
-
- /* Set up the uart parameters in the parameter ram.
- */
- up->smc_rbase = dpaddr;
- up->smc_tbase = dpaddr+sizeof(cbd_t);
- up->smc_rfcr = SMC_EB;
- up->smc_tfcr = SMC_EB;
-
- /* Set UART mode, 8 bit, no parity, one stop.
- * Enable receive and transmit.
- */
- sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART;
-
- /* Mask all interrupts and remove anything pending.
- */
- sp->smc_smcm = 0;
- sp->smc_smce = 0xff;
-
- /* Set up the baud rate generator.
- * See 8xx_io/commproc.c for details.
- * This wires BRG1 to SMC1 and BRG2 to SMC2;
- */
- cp->cp_simode = 0x10000000;
-#ifdef TQM_SMC2_CONSOLE
- cp->cp_brgc2 =
-#else
- cp->cp_brgc1 =
-#endif
- ((((bd->bi_intfreq * 1000000)/16) / bd->bi_baudrate) << 1) | CPM_BRG_EN;
-
-#else /* CONFIG_MBX */
- if (*MBX_CSR1 & CSR1_COMEN) {
- /* COM1 is enabled. Initialize SMC1 and use it for
- * the console port.
- */
-
- /* Enable SDMA.
- */
- ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1;
-
- /* Use Port B for SMCs instead of other functions.
- */
- cp->cp_pbpar |= 0x00000cc0;
- cp->cp_pbdir &= ~0x00000cc0;
- cp->cp_pbodr &= ~0x00000cc0;
-
- /* Allocate space for two buffer descriptors in the DP ram.
- * For now, this address seems OK, but it may have to
- * change with newer versions of the firmware.
- */
- dpaddr = 0x0800;
-
- /* Grab a few bytes from the top of memory. EPPC-Bug isn't
- * running any more, so we can do this.
- */
- memaddr = (bd->bi_memsize - 32) & ~15;
-
- /* Set the physical address of the host memory buffers in
- * the buffer descriptors.
- */
- rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr];
- rbdf->cbd_bufaddr = memaddr;
- rbdf->cbd_sc = 0;
- tbdf = rbdf + 1;
- tbdf->cbd_bufaddr = memaddr+4;
- tbdf->cbd_sc = 0;
-
- /* Set up the uart parameters in the parameter ram.
- */
- up->smc_rbase = dpaddr;
- up->smc_tbase = dpaddr+sizeof(cbd_t);
- up->smc_rfcr = SMC_EB;
- up->smc_tfcr = SMC_EB;
-
- /* Set UART mode, 8 bit, no parity, one stop.
- * Enable receive and transmit.
- */
- sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART;
-
- /* Mask all interrupts and remove anything pending.
- */
- sp->smc_smcm = 0;
- sp->smc_smce = 0xff;
-
- /* Set up the baud rate generator.
- * See 8xx_io/commproc.c for details.
- */
- cp->cp_simode = 0x10000000;
- cp->cp_brgc1 =
- ((((bd->bi_intfreq * 1000000)/16) / 9600) << 1) | CPM_BRG_EN;
-
- /* Enable SMC1 for console output.
- */
- *MBX_CSR1 &= ~CSR1_COMEN;
- }
- else {
-#endif /* ndef CONFIG_MBX */
- /* SMCx is used as console port.
- */
- tbdf = (cbd_t *)&cp->cp_dpmem[up->smc_tbase];
- rbdf = (cbd_t *)&cp->cp_dpmem[up->smc_rbase];
-
- /* Issue a stop transmit, and wait for it.
- */
- cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS,
- CPM_CR_STOP_TX) | CPM_CR_FLG;
- while (cp->cp_cpcr & CPM_CR_FLG);
- }
-
- /* Make the first buffer the only buffer.
- */
- tbdf->cbd_sc |= BD_SC_WRAP;
- rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
-
- /* Single character receive.
- */
- up->smc_mrblr = 1;
- up->smc_maxidl = 0;
-
- /* Initialize Tx/Rx parameters.
- */
- cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, CPM_CR_INIT_TRX) | CPM_CR_FLG;
- while (cp->cp_cpcr & CPM_CR_FLG);
-
- /* Enable transmitter/receiver.
- */
- sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
-}
-
-void
-serial_putchar(const char c)
-{
- volatile cbd_t *tbdf;
- volatile char *buf;
- volatile smc_uart_t *up;
-
- up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];
- tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];
-
- /* Wait for last character to go.
- */
- buf = (char *)tbdf->cbd_bufaddr;
- while (tbdf->cbd_sc & BD_SC_READY);
-
- *buf = c;
- tbdf->cbd_datlen = 1;
- tbdf->cbd_sc |= BD_SC_READY;
-}
-
-char
-serial_getc()
-{
- volatile cbd_t *rbdf;
- volatile char *buf;
- volatile smc_uart_t *up;
- char c;
-
- up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];
- rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
-
- /* Wait for character to show up.
- */
- buf = (char *)rbdf->cbd_bufaddr;
- while (rbdf->cbd_sc & BD_SC_EMPTY);
- c = *buf;
- rbdf->cbd_sc |= BD_SC_EMPTY;
-
- return(c);
-}
-
-int
-serial_tstc()
-{
- volatile cbd_t *rbdf;
- volatile smc_uart_t *up;
-
- up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];
- rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
-
- return(!(rbdf->cbd_sc & BD_SC_EMPTY));
-}
+++ /dev/null
-/*
- * misc.c
- *
- * $Id: misc.c,v 1.2 1999/09/14 05:55:29 dmalek Exp $
- *
- * Adapted for PowerPC by Gary Thomas
- *
- * Rewritten by Cort Dougan (cort@cs.nmt.edu)
- * One day to be replaced by a single bootloader for chrp/prep/pmac. -- Cort
- */
-
-#include <linux/types.h>
-#include "../coffboot/zlib.h"
-#include "asm/residual.h"
-#include <linux/elf.h>
-#include <linux/config.h>
-#include <asm/page.h>
-#include <asm/processor.h>
-#include <asm/mmu.h>
-#ifdef CONFIG_8xx
-#include <asm/mpc8xx.h>
-#endif
-#ifdef CONFIG_8260
-#include <asm/mpc8260.h>
-#endif
-
-/*
- * The following references are needed to cause the linker to pull in the
- * gzimage.o and rdimage.o files. These object files are special,
- * since they get placed into the .gzimage and .rdimage ELF sections
- * of the zvmlinux and zvmlinux.initrd files.
- */
-extern char dummy_for_gzimage;
-extern char dummy_for_rdimage;
-
-/*
- * Please send me load/board info and such data for hardware not
- * listed here so I can keep track since things are getting tricky
- * with the different load addrs with different firmware. This will
- * help to avoid breaking the load/boot process.
- * -- Cort
- */
-char *avail_ram;
-char *end_avail;
-
-/* See comment below.....
-*/
-unsigned int initrd_offset, initrd_size;
-
-/* Because of the limited amount of memory on embedded, it presents
- * loading problems. The biggest is that we load this boot program
- * into a relatively low memory address, and the Linux kernel Bss often
- * extends into this space when it get loaded. When the kernel starts
- * and zeros the BSS space, it also writes over the information we
- * save here and pass to the kernel (command line and board info).
- * On these boards, we grab some known memory holes to hold this information.
- */
-char cmd_buf[256];
-char *cmd_line = cmd_buf;
-
-char *root_string = "root=/dev/nfs rw";
-char *nfsaddrs_string = "nfsaddrs=";
-char *nfsroot_string = "nfsroot=";
-char *defroot_string = "/sys/mbxroot";
-char *ramroot_string = "root=/dev/ram";
-int do_ipaddrs(char **cmd_cp, int echo);
-void do_nfsroot(char **cmd_cp, char *dp);
-int strncmp(const char * cs,const char * ct,size_t count);
-char *strrchr(const char * s, int c);
-
-bd_t hold_resid_buf;
-bd_t *hold_residual = &hold_resid_buf;
-unsigned long initrd_start = 0, initrd_end = 0;
-char *zimage_start;
-int zimage_size;
-
-void puts(const char *);
-void putc(const char c);
-void puthex(unsigned long val);
-void _bcopy(char *src, char *dst, int len);
-void * memcpy(void * __dest, __const void * __src,
- int __n);
-void gunzip(void *, int, unsigned char *, int *);
-
-void pause()
-{
- puts("pause\n");
-}
-
-void exit()
-{
- puts("exit\n");
- while(1);
-}
-
-/* The MPC8xx is just the serial port.
-*/
-tstc(void)
-{
- return (serial_tstc());
-}
-
-getc(void)
-{
- while (1) {
- if (serial_tstc()) return (serial_getc());
- }
-}
-
-void
-putc(const char c)
-{
- serial_putchar(c);
-}
-
-void puts(const char *s)
-{
- char c;
-
- while ( ( c = *s++ ) != '\0' ) {
- serial_putchar(c);
- if ( c == '\n' )
- serial_putchar('\r');
- }
-}
-
-void * memcpy(void * __dest, __const void * __src,
- int __n)
-{
- int i;
- char *d = (char *)__dest, *s = (char *)__src;
-
- for (i=0;i<__n;i++) d[i] = s[i];
-}
-
-int memcmp(__const void * __dest, __const void * __src,
- int __n)
-{
- int i;
- char *d = (char *)__dest, *s = (char *)__src;
-
- for (i=0;i<__n;i++, d++, s++)
- {
- if (*d != *s)
- {
- return (*s - *d);
- }
- }
- return (0);
-}
-
-void error(char *x)
-{
- puts("\n\n");
- puts(x);
- puts("\n\n -- System halted");
-
- while(1); /* Halt */
-}
-
-void *zalloc(void *x, unsigned items, unsigned size)
-{
- void *p = avail_ram;
-
- size *= items;
- size = (size + 7) & -8;
- avail_ram += size;
- if (avail_ram > end_avail) {
- puts("oops... out of memory\n");
- pause();
- }
- return p;
-}
-
-void zfree(void *x, void *addr, unsigned nb)
-{
-}
-
-#define HEAD_CRC 2
-#define EXTRA_FIELD 4
-#define ORIG_NAME 8
-#define COMMENT 0x10
-#define RESERVED 0xe0
-
-#define DEFLATED 8
-
-
-void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
-{
- z_stream s;
- int r, i, flags;
-
- /* skip header */
- i = 10;
- flags = src[3];
- if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
- puts("bad gzipped data\n");
- exit();
- }
- if ((flags & EXTRA_FIELD) != 0)
- i = 12 + src[10] + (src[11] << 8);
- if ((flags & ORIG_NAME) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & COMMENT) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & HEAD_CRC) != 0)
- i += 2;
- if (i >= *lenp) {
- puts("gunzip: ran out of data in header\n");
- exit();
- }
-
- s.zalloc = zalloc;
- s.zfree = zfree;
- r = inflateInit2(&s, -MAX_WBITS);
- if (r != Z_OK) {
- puts("inflateInit2 returned %d\n");
- exit();
- }
- s.next_in = src + i;
- s.avail_in = *lenp - i;
- s.next_out = dst;
- s.avail_out = dstlen;
- r = inflate(&s, Z_FINISH);
- if (r != Z_OK && r != Z_STREAM_END) {
- puts("inflate returned ");
- puthex(r);
- puts("\n");
- exit();
- }
- *lenp = s.next_out - (unsigned char *) dst;
- inflateEnd(&s);
-}
-
-unsigned char sanity[0x2000];
-
-unsigned long
-decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, bd_t *bp)
-{
- int timer;
- extern unsigned long start;
- char *cp, ch;
- unsigned long i;
- char *dp;
-
-#ifdef CONFIG_8260
- /* I don't know why I didn't do it this way on the 8xx.......
- */
- embed_config(bp);
- serial_init(bp);
-#endif
-
- /* These values must be variables. If not, the compiler optimizer
- * will remove some code, causing the size of the code to vary
- * when these values are zero. This is bad because we first
- * compile with these zero to determine the size and offsets
- * in an image, than compile again with these set to the proper
- * discovered value.....Ya know, we used to read these from the
- * header a long time ago.....
- */
- initrd_offset = INITRD_OFFSET;
- initrd_size = INITRD_SIZE;
-
- /* Grab some space for the command line and board info. Since
- * we no longer use the ELF header, but it was loaded, grab
- * that space.
- */
-#ifdef CONFIG_MBX
- cmd_line = (char *)(load_addr - 0x10000);
-
- /* To be like everyone else, we need one too, although this
- * board information is passed from the boot rom.
- */
- bp->bi_baudrate = 9600;
-#else
- cmd_line = (char *)(0x200000);
-#endif
- hold_residual = (bd_t *)(cmd_line + sizeof(cmd_buf));
- /* copy board data */
- if (bp)
- memcpy(hold_residual,bp,sizeof(bd_t));
-
- /* Set end of memory available to us. It is always the highest
- * memory address provided by the board information.
- */
- end_avail = (char *)(bp->bi_memsize);
-
- puts("loaded at: "); puthex(load_addr);
- puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n");
- if ( (unsigned long)load_addr != (unsigned long)&start )
- {
- puts("relocated to: "); puthex((unsigned long)&start);
- puts(" ");
- puthex((unsigned long)((unsigned long)&start + (4*num_words)));
- puts("\n");
- }
-
- if ( bp )
- {
- puts("board data at: "); puthex((unsigned long)bp);
- puts(" ");
- puthex((unsigned long)((unsigned long)bp + sizeof(bd_t)));
- puts("\n");
- puts("relocated to: ");
- puthex((unsigned long)hold_residual);
- puts(" ");
- puthex((unsigned long)((unsigned long)hold_residual + sizeof(bd_t)));
- puts("\n");
- }
-
- /* we have to subtract 0x10000 here to correct for objdump including the
- size of the elf header which we strip -- Cort */
- zimage_start = (char *)(load_addr - 0x10000 + ZIMAGE_OFFSET);
- zimage_size = ZIMAGE_SIZE;
-
- if ( initrd_offset )
- initrd_start = load_addr - 0x10000 + initrd_offset;
- else
- initrd_start = 0;
- initrd_end = initrd_size + initrd_start;
-
- /*
- * setup avail_ram - this is the first part of ram usable
- * by the uncompress code. -- Cort
- */
- avail_ram = (char *)PAGE_ALIGN((unsigned long)zimage_start+zimage_size);
- if ( ((load_addr+(num_words*4)) > (unsigned long) avail_ram)
- && (load_addr <= 0x01000000) )
- avail_ram = (char *)(load_addr+(num_words*4));
- if ( (((unsigned long)&start+(num_words*4)) > (unsigned long) avail_ram)
- && (load_addr <= 0x01000000) )
- avail_ram = (char *)((unsigned long)&start+(num_words*4));
-
- /* relocate zimage */
- puts("zimage at: "); puthex((unsigned long)zimage_start);
- puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); puts("\n");
- /*
- * There is no reason (yet) to relocate zImage for embedded boards.
- * To support boot from flash rom on 8xx embedded boards, I
- * assume if zimage start is over 16M we are booting from flash.
- * In this case, avilable ram will start just above the space we
- * have allocated for the command buffer and board information.
- */
- if ((unsigned long)zimage_start > 0x01000000)
- avail_ram = (char *)PAGE_ALIGN((unsigned long)hold_residual + sizeof(bd_t));
-
- /* relocate initrd */
- if ( initrd_start )
- {
- puts("initrd at: "); puthex(initrd_start);
- puts(" "); puthex(initrd_end); puts("\n");
-
- /* We only have to relocate initrd if we find it is in Flash
- * rom. This is because the kernel thinks it can toss the
- * pages into the free memory pool after it is done. Use
- * the same 16M test.
- */
- if ((unsigned long)initrd_start > 0x01000000) {
- memcpy ((void *)PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-INITRD_SIZE),
- (void *)initrd_start,
- initrd_size );
- initrd_start = PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-INITRD_SIZE);
- initrd_end = initrd_start + initrd_size;
- end_avail = (char *)initrd_start;
- puts("relocated to: "); puthex(initrd_start);
- puts(" "); puthex(initrd_end); puts("\n");
- }
- else {
- avail_ram = (char *)PAGE_ALIGN((unsigned long)initrd_end);
- }
- }
-
-
- puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" ");
- puthex((unsigned long)end_avail); puts("\n");
-
- puts("\nLinux/PPC load: ");
- timer = 0;
- cp = cmd_line;
-
- while (timer++ < 5*1000) {
- if (tstc()) {
- while ((ch = getc()) != '\n' && ch != '\r') {
- if (ch == '\b') {
- if (cp != cmd_line) {
- cp--;
- puts("\b \b");
- }
- } else {
- *cp++ = ch;
- putc(ch);
- }
- }
- break; /* Exit 'timer' loop */
- }
- udelay(1000); /* 1 msec */
- }
- *cp = 0;
-
- /* If the command line is not filled in, we will automatically
- * create the default boot.
- */
- if (cmd_line[0] == 0) {
-
- /* An initrd on these boards means we booted from Flash
- * ROM and want to use the ramdisk as the root file system.
- * Otherwise, we perform a diskless NFS boot.
- */
- if (initrd_start)
- dp = ramroot_string;
- else
- dp = root_string;
- while (*dp != 0)
- *cp++ = *dp++;
- *cp = 0;
- }
-
- puts("\n");
-
- puts("Uncompressing Linux...");
-
- gunzip(0, 0x400000, zimage_start, &zimage_size);
- puts("done.\n");
- puts("Now booting the kernel\n");
- return (unsigned long)hold_residual;
-}
-
-void puthex(unsigned long val)
-{
- unsigned char buf[10];
- int i;
- for (i = 7; i >= 0; i--)
- {
- buf[i] = "0123456789ABCDEF"[val & 0x0F];
- val >>= 4;
- }
- buf[8] = '\0';
- puts(buf);
-}
-
-/*
- * PCI/ISA I/O support
- */
-
-volatile unsigned char *ISA_io = (unsigned char *)0x80000000;
-volatile unsigned char *ISA_mem = (unsigned char *)0xC0000000;
-
-void
-outb(int port, char val)
-{
- /* Ensure I/O operations complete */
- __asm__ volatile("eieio");
- ISA_io[port] = val;
-}
-
-unsigned char
-inb(int port)
-{
- /* Ensure I/O operations complete */
- __asm__ volatile("eieio");
- return (ISA_io[port]);
-}
-
-unsigned long
-local_to_PCI(unsigned long addr)
-{
- return ((addr & 0x7FFFFFFF) | 0x80000000);
-}
-
-void
-_bcopy(char *src, char *dst, int len)
-{
- while (len--) *dst++ = *src++;
-}
+++ /dev/null
-/* Stand alone funtions for QSpan Tundra support.
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <asm/mpc8xx.h>
-
-/* To map PCI devices, you first write 0xffffffff into the device
- * base address registers. When the register is read back, the
- * number of most significant '1' bits describes the amount of address
- * space needed for mapping. If the most significant bit is not set,
- * either the device does not use that address register, or it has
- * a fixed address that we can't change. After the address is assigned,
- * the command register has to be written to enable the card.
- */
-typedef struct {
- u_char pci_bus;
- u_char pci_devfn;
- ushort pci_command;
- uint pci_addrs[6];
-} pci_map_t;
-
-/* We should probably dynamically allocate these structures.
-*/
-#define MAX_PCI_DEVS 32
-int pci_dev_cnt;
-pci_map_t pci_map[MAX_PCI_DEVS];
-
-void pci_conf_write(int bus, int device, int func, int reg, uint writeval);
-void pci_conf_read(int bus, int device, int func, int reg, void *readval);
-void probe_addresses(int bus, int devfn);
-void map_pci_addrs(void);
-
-/* This is a really stripped version of PCI bus scan. All we are
- * looking for are devices that exist.
- */
-pci_scanner(int addr_probe)
-{
- unsigned int devfn, l, max, class, bus_number;
- unsigned char cmd, irq, tmp, hdr_type, is_multi;
- int reg;
-
- is_multi = 0;
- bus_number = 0;
- for (devfn = 0; devfn < 0xff; ++devfn) {
- /* The device numbers are comprised of upper 5 bits of
- * device number and lower 3 bits of multi-function number.
- */
- if ((devfn & 7) && !is_multi) {
- /* Don't scan multifunction addresses if this is
- * not a multifunction device.
- */
- continue;
- }
-
- /* Read the header to determine card type.
- */
- qs_pci_read_config_byte(bus_number, devfn, PCI_HEADER_TYPE,
- &hdr_type);
-
- /* If this is a base device number, check the header to
- * determine if it is mulifunction.
- */
- if ((devfn & 7) == 0)
- is_multi = hdr_type & 0x80;
-
- /* Check to see if the board is really in the slot.
- */
- qs_pci_read_config_dword(bus_number, devfn, PCI_VENDOR_ID, &l);
- /* some broken boards return 0 if a slot is empty: */
- if (l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff ||
- l == 0xffff0000) {
- /* Nothing there.
- */
- is_multi = 0;
- continue;
- }
-
- /* If we are not performing an address probe,
- * just simply print out some information.
- */
- if (!addr_probe) {
- qs_pci_read_config_dword(bus_number, devfn,
- PCI_CLASS_REVISION, &class);
-
- class >>= 8; /* upper 3 bytes */
-
-#if 0
- printf("Found (%3d:%d): vendor 0x%04x, device 0x%04x, class 0x%06x\n",
- (devfn >> 3), (devfn & 7),
- (l & 0xffff), (l >> 16) & 0xffff, class);
-#else
- puts("Found ("); puthex(devfn >> 3);
- puts(":"); puthex(devfn & 7);
- puts("): vendor "); puthex(l & 0xffff);
- puts(", device "); puthex((l >> 16) & 0xffff);
- puts(", class "); puthex(class); puts("\n");
-#endif
- }
- else {
- /* If this is a "normal" device, build address list.
- */
- if ((hdr_type & 0x7f) == PCI_HEADER_TYPE_NORMAL)
- probe_addresses(bus_number, devfn);
- }
- }
-
- /* Now map the boards.
- */
- if (addr_probe)
- map_pci_addrs();
-}
-
-/* Probe addresses for the specified device. This is a destructive
- * operation because it writes the registers.
- */
-void
-probe_addresses(bus, devfn)
-{
- int i;
- uint pciaddr;
- ushort pcicmd;
- pci_map_t *pm;
-
- if (pci_dev_cnt >= MAX_PCI_DEVS) {
- puts("Too many PCI devices\n");
- return;
- }
-
- pm = &pci_map[pci_dev_cnt++];
-
- pm->pci_bus = bus;
- pm->pci_devfn = devfn;
-
- for (i=0; i<6; i++) {
- qs_pci_write_config_dword(bus, devfn, PCI_BASE_ADDRESS_0 + (i * 4), -1);
- qs_pci_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0 + (i * 4),
- &pciaddr);
- pm->pci_addrs[i] = pciaddr;
- qs_pci_read_config_word(bus, devfn, PCI_COMMAND, &pcicmd);
- pm->pci_command = pcicmd;
- }
-}
-
-/* Map the cards into the PCI space. The PCI has separate memory
- * and I/O spaces. In addition, some memory devices require mapping
- * below 1M. The least significant 4 bits of the address register
- * provide information. If this is an I/O device, only the LS bit
- * is used to indicate that, so I/O devices can be mapped to a two byte
- * boundard. Memory addresses can be mapped to a 32 byte boundary.
- * The QSpan implementations usually have a 1Gbyte space for each
- * memory and I/O spaces.
- *
- * This isn't a terribly fancy algorithm. I just map the spaces from
- * the top starting with the largest address space. When finished,
- * the registers are written and the card enabled.
- *
- * While the Tundra can map a large address space on most boards, we
- * need to be careful because it may overlap other devices (like IMMR).
- */
-#define MEMORY_SPACE_SIZE 0x20000000
-#define IO_SPACE_SIZE 0x20000000
-
-void
-map_pci_addrs()
-{
- uint pci_mem_top, pci_mem_low;
- uint pci_io_top;
- uint addr_mask, reg_addr, space;
- int i, j;
- pci_map_t *pm;
-
- pci_mem_top = MEMORY_SPACE_SIZE;
- pci_io_top = IO_SPACE_SIZE;
- pci_mem_low = (1 * 1024 * 1024); /* Below one meg addresses */
-
- /* We can't map anything more than the maximum space, but test
- * for it anyway to catch devices out of range.
- */
- addr_mask = 0x80000000;
-
- do {
- space = (~addr_mask) + 1; /* Size of the space */
- for (i=0; i<pci_dev_cnt; i++) {
- pm = &pci_map[i];
- for (j=0; j<6; j++) {
- /* If the MS bit is not set, this has either
- * already been mapped, or is not used.
- */
- reg_addr = pm->pci_addrs[j];
- if ((reg_addr & 0x80000000) == 0)
- continue;
- if (reg_addr & PCI_BASE_ADDRESS_SPACE_IO) {
- if ((reg_addr & PCI_BASE_ADDRESS_IO_MASK) != addr_mask)
- continue;
- if (pci_io_top < space) {
- puts("Out of PCI I/O space\n");
- }
- else {
- pci_io_top -= space;
- pm->pci_addrs[j] = pci_io_top;
- pm->pci_command |= PCI_COMMAND_IO;
- }
- }
- else {
- if ((reg_addr & PCI_BASE_ADDRESS_MEM_MASK) != addr_mask)
- continue;
-
- /* Memory space. Test if below 1M.
- */
- if (reg_addr & PCI_BASE_ADDRESS_MEM_TYPE_1M) {
- if (pci_mem_low < space) {
- puts("Out of PCI 1M space\n");
- }
- else {
- pci_mem_low -= space;
- pm->pci_addrs[j] = pci_mem_low;
- }
- }
- else {
- if (pci_mem_top < space) {
- puts("Out of PCI Mem space\n");
- }
- else {
- pci_mem_top -= space;
- pm->pci_addrs[j] = pci_mem_top;
- }
- }
- pm->pci_command |= PCI_COMMAND_MEMORY;
- }
- }
- }
- addr_mask >>= 1;
- addr_mask |= 0x80000000;
- } while (addr_mask != 0xfffffffe);
-
- /* Now, run the list one more time and map everything.
- */
- for (i=0; i<pci_dev_cnt; i++) {
- pm = &pci_map[i];
- for (j=0; j<6; j++) {
- qs_pci_write_config_dword(pm->pci_bus, pm->pci_devfn,
- PCI_BASE_ADDRESS_0 + (j * 4), pm->pci_addrs[j]);
- }
-
- /* Enable memory or address mapping.
- */
- qs_pci_write_config_word(pm->pci_bus, pm->pci_devfn, PCI_COMMAND,
- pm->pci_command);
- }
-}
-
+++ /dev/null
-/*
- * LinuxPPC arch/ppc/kernel/qspan_pci.c Dan Malek (dmalek@jlc.net)
- *
- * QSpan Motorola bus to PCI bridge. The config address register
- * is located 0x500 from the base of the bridge control/status registers.
- * The data register is located at 0x504.
- * This is a two step operation. First, the address register is written,
- * then the data register is read/written as required.
- * I don't know what to do about interrupts (yet).
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <asm/mpc8xx.h>
-
-/*
- * When reading the configuration space, if something does not respond
- * the bus times out and we get a machine check interrupt. So, the
- * good ol' exception tables come to mind to trap it and return some
- * value.
- *
- * On an error we just return a -1, since that is what the caller wants
- * returned if nothing is present. I copied this from __get_user_asm,
- * with the only difference of returning -1 instead of EFAULT.
- * There is an associated hack in the machine check trap code.
- *
- * The QSPAN is also a big endian device, that is it makes the PCI
- * look big endian to us. This presents a problem for the Linux PCI
- * functions, which assume little endian. For example, we see the
- * first 32-bit word like this:
- * ------------------------
- * | Device ID | Vendor ID |
- * ------------------------
- * If we read/write as a double word, that's OK. But in our world,
- * when read as a word, device ID is at location 0, not location 2 as
- * the little endian PCI would believe. We have to switch bits in
- * the PCI addresses given to us to get the data to/from the correct
- * byte lanes.
- *
- * The QSPAN only supports 4 bits of "slot" in the dev_fn instead of 5.
- * It always forces the MS bit to zero. Therefore, dev_fn values
- * greater than 128 are returned as "no device found" errors.
- *
- * The QSPAN can only perform long word (32-bit) configuration cycles.
- * The "offset" must have the two LS bits set to zero. Read operations
- * require we read the entire word and then sort out what should be
- * returned. Write operations other than long word require that we
- * read the long word, update the proper word or byte, then write the
- * entire long word back.
- *
- * PCI Bridge hack. We assume (correctly) that bus 0 is the primary
- * PCI bus from the QSPAN. If we are called with a bus number other
- * than zero, we create a Type 1 configuration access that a downstream
- * PCI bridge will interpret.
- */
-
-#define __get_pci_config(x, addr, op) \
- __asm__ __volatile__( \
- "1: "op" %0,0(%1)\n" \
- " eieio\n" \
- "2:\n" \
- ".section .fixup,\"ax\"\n" \
- "3: li %0,-1\n" \
- " b 2b\n" \
- ".section __ex_table,\"a\"\n" \
- " .align 2\n" \
- " .long 1b,3b\n" \
- ".text" \
- : "=r"(x) : "r"(addr))
-
-#define QS_CONFIG_ADDR ((volatile uint *)(PCI_CSR_ADDR + 0x500))
-#define QS_CONFIG_DATA ((volatile uint *)(PCI_CSR_ADDR + 0x504))
-
-#define mk_config_addr(bus, dev, offset) \
- (((bus)<<16) | ((dev)<<8) | (offset & 0xfc))
-
-#define mk_config_type1(bus, dev, offset) \
- mk_config_addr(bus, dev, offset) | 1;
-
-/* Initialize the QSpan device registers after power up.
-*/
-qspan_init()
-{
- uint *qptr;
-
-
-
- qptr = (uint *)PCI_CSR_ADDR;
-
- /* PCI Configuration/status. Upper bits written to clear
- * pending interrupt or status. Lower bits enable QSPAN as
- * PCI master, enable memory and I/O cycles, and enable PCI
- * parity error checking.
- * IMPORTANT: The last two bits of this word enable PCI
- * master cycles into the QBus. The QSpan is broken and can't
- * meet the timing specs of the PQ bus for this to work. Therefore,
- * if you don't have external bus arbitration, you can't use
- * this function.
- */
-#ifdef EXTERNAL_PQ_ARB
- qptr[1] = 0xf9000147;
-#else
- qptr[1] = 0xf9000144;
-#endif
-
- /* PCI Misc configuration. Set PCI latency timer resolution
- * of 8 cycles, set cache size to 4 x 32.
- */
- qptr[3] = 0;
-
- /* Set up PCI Target address mapping. Enable, Posted writes,
- * 2Gbyte space (processor memory controller determines actual size).
- */
- qptr[64] = 0x8f000080;
-
- /* Map processor 0x80000000 to PCI 0x00000000.
- * Processor address bit 1 determines I/O type access (0x80000000)
- * or memory type access (0xc0000000).
- */
- qptr[65] = 0x80000000;
-
- /* Enable error logging and clear any pending error status.
- */
- qptr[80] = 0x90000000;
-
- qptr[512] = 0x000c0003;
-
- /* Set up Qbus slave image.
- */
- qptr[960] = 0x01000000;
- qptr[961] = 0x000000d1;
- qptr[964] = 0x00000000;
- qptr[965] = 0x000000d1;
-
-}
-
-/* Functions to support PCI bios-like features to read/write configuration
- * space. If the function fails for any reason, a -1 (0xffffffff) value
- * must be returned.
- */
-#define DEVICE_NOT_FOUND (-1)
-#define SUCCESSFUL 0
-
-int qs_pci_read_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char *val)
-{
- uint temp;
- u_char *cp;
-
- if ((bus > 7) || (dev_fn > 127)) {
- *val = 0xff;
- return DEVICE_NOT_FOUND;
- }
-
- if (bus == 0)
- *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
- else
- *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
- __get_pci_config(temp, QS_CONFIG_DATA, "lwz");
-
- offset ^= 0x03;
- cp = ((u_char *)&temp) + (offset & 0x03);
- *val = *cp;
- return SUCCESSFUL;
-}
-
-int qs_pci_read_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short *val)
-{
- uint temp;
- ushort *sp;
-
- if ((bus > 7) || (dev_fn > 127)) {
- *val = 0xffff;
- return DEVICE_NOT_FOUND;
- }
-
- if (bus == 0)
- *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
- else
- *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
- __get_pci_config(temp, QS_CONFIG_DATA, "lwz");
- offset ^= 0x02;
-
- sp = ((ushort *)&temp) + ((offset >> 1) & 1);
- *val = *sp;
- return SUCCESSFUL;
-}
-
-int qs_pci_read_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int *val)
-{
- if ((bus > 7) || (dev_fn > 127)) {
- *val = 0xffffffff;
- return DEVICE_NOT_FOUND;
- }
- if (bus == 0)
- *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
- else
- *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
- __get_pci_config(*val, QS_CONFIG_DATA, "lwz");
- return SUCCESSFUL;
-}
-
-int qs_pci_write_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char val)
-{
- uint temp;
- u_char *cp;
-
- if ((bus > 7) || (dev_fn > 127))
- return DEVICE_NOT_FOUND;
-
- qs_pci_read_config_dword(bus, dev_fn, offset, &temp);
-
- offset ^= 0x03;
- cp = ((u_char *)&temp) + (offset & 0x03);
- *cp = val;
-
- if (bus == 0)
- *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
- else
- *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
- *QS_CONFIG_DATA = temp;
-
- return SUCCESSFUL;
-}
-
-int qs_pci_write_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short val)
-{
- uint temp;
- ushort *sp;
-
- if ((bus > 7) || (dev_fn > 127))
- return DEVICE_NOT_FOUND;
-
- qs_pci_read_config_dword(bus, dev_fn, offset, &temp);
-
- offset ^= 0x02;
- sp = ((ushort *)&temp) + ((offset >> 1) & 1);
- *sp = val;
-
- if (bus == 0)
- *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
- else
- *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
- *QS_CONFIG_DATA = temp;
-
- return SUCCESSFUL;
-}
-
-int qs_pci_write_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int val)
-{
- if ((bus > 7) || (dev_fn > 127))
- return DEVICE_NOT_FOUND;
-
- if (bus == 0)
- *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
- else
- *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
- *(unsigned int *)QS_CONFIG_DATA = val;
-
- return SUCCESSFUL;
-}
-
+++ /dev/null
-/*
- * rdimage.c
- *
- * Dummy file to allow a compressed initrd to be added
- * into a linker section, accessed by the boot coode
- */
-
-char dummy_for_rdimage;
+++ /dev/null
-#
-# Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
-#
-# Module name: Makefile
-#
-# Description:
-# Makefile for the IBM "tree" evaluation board Linux kernel
-# boot loaders.
-#
-
-HOSTCFLAGS = -O -I$(TOPDIR)/include
-
-GZIP = gzip -vf9
-RM = rm -f
-MKEVIMG = mkevimg -l
-MKIRIMG = mkirimg
-
-CFLAGS = -O -fno-builtin -I$(TOPDIR)/include
-LD_ARGS = -e _start -T ld.script -Ttext 0x00200000 -Bstatic
-
-OBJS = crt0.o main.o misc.o irSect.o ../coffboot/string.o ../coffboot/zlib.o
-LIBS =
-
-treeboot: $(OBJS) ld.script
- $(LD) -o $@ $(LD_ARGS) $(OBJS) $(LIBS)
-
-zImage: vmlinux.img
-
-zImage.initrd: vmlinux.initrd.img
-
-treeboot.image: treeboot vmlinux.gz
- $(OBJCOPY) --add-section=image=vmlinux.gz treeboot $@
-
-treeboot.initrd: treeboot.image ramdisk.image.gz
- $(OBJCOPY) --add-section=initrd=ramdisk.image.gz treeboot.image $@
-
-vmlinux.img: treeboot.image
- $(OBJDUMP) --syms treeboot.image | grep irSectStart > irSectStart.txt
- $(MKIRIMG) treeboot.image treeboot.image.out irSectStart.txt
- $(MKEVIMG) treeboot.image.out $@
- $(RM) treeboot.image treeboot.image.out irSectStart.txt
-
-vmlinux.initrd.img: treeboot.initrd
- $(OBJDUMP) --all-headers treeboot.initrd | grep irSectStart > irSectStart.txt
- $(MKIRIMG) treeboot.initrd treeboot.initrd.out irSectStart.txt
- $(MKEVIMG) treeboot.initrd.out $@
- $(RM) treeboot.initrd treeboot.initrd.out irSectStart.txt
-
-vmlinux.gz: $(TOPDIR)/vmlinux
- $(OBJCOPY) -S -O binary $(TOPDIR)/vmlinux vmlinux
- $(GZIP) vmlinux
-
-clean:
- rm -f treeboot treeboot.image treeboot.initrd irSectStart.txt vmlinux.* *.o
-
-fastdep:
-
+++ /dev/null
-#
-# ELF header field numbers
-#
-
-$e_ident = 0; # Identification bytes / magic number
-$e_type = 1; # ELF file type
-$e_machine = 2; # Target machine type
-$e_version = 3; # File version
-$e_entry = 4; # Start address
-$e_phoff = 5; # Program header file offset
-$e_shoff = 6; # Section header file offset
-$e_flags = 7; # File flags
-$e_ehsize = 8; # Size of ELF header
-$e_phentsize = 9; # Size of program header
-$e_phnum = 10; # Number of program header entries
-$e_shentsize = 11; # Size of section header
-$e_shnum = 12; # Number of section header entries
-$e_shstrndx = 13; # Section header table string index
-
-#
-# Section header field numbers
-#
-
-$sh_name = 0; # Section name
-$sh_type = 1; # Section header type
-$sh_flags = 2; # Section header flags
-$sh_addr = 3; # Virtual address
-$sh_offset = 4; # File offset
-$sh_size = 5; # Section size
-$sh_link = 6; # Miscellaneous info
-$sh_info = 7; # More miscellaneous info
-$sh_addralign = 8; # Memory alignment
-$sh_entsize = 9; # Entry size if this is a table
+++ /dev/null
-/*
- *
- * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
- *
- * Module name: irSect.c
- *
- * Description:
- * Defines variables to hold the absolute starting address and size
- * of the Linux kernel "image" and the initial RAM disk "initrd"
- * sections within the boot loader.
- *
- */
-
-#include "irSect.h"
-
-
-/*
- * The order of globals below must not change. If more globals are added,
- * you must change the script 'mkirimg' accordingly.
- *
- */
-
-/*
- * irSectStart must be at beginning of file
- */
-unsigned int irSectStart = 0xdeadbeaf;
-
-unsigned int imageSect_start = 0;
-unsigned int imageSect_size = 0;
-unsigned int initrdSect_start = 0;
-unsigned int initrdSect_size = 0;
-
-/*
- * irSectEnd must be at end of file
- */
-unsigned int irSectEnd = 0xdeadbeaf;
+++ /dev/null
-/*
- *
- * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
- *
- * Module name: irSect.h
- *
- * Description:
- * Defines variables to hold the absolute starting address and size
- * of the Linux kernel "image" and the initial RAM disk "initrd"
- * sections within the boot loader.
- *
- */
-
-#ifndef __IRSECT_H__
-#define __IRSECT_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern unsigned int imageSect_start;
-extern unsigned int imageSect_size;
-
-extern unsigned int initrdSect_start;
-extern unsigned int initrdSect_size;
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __IRSECT_H__ */
+++ /dev/null
-OUTPUT_ARCH(powerpc)
-SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
-/* Do we need any of these for elf?
- __DYNAMIC = 0; */
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- . = + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .rel.text : { *(.rel.text) }
- .rela.text : { *(.rela.text) }
- .rel.data : { *(.rel.data) }
- .rela.data : { *(.rela.data) }
- .rel.rodata : { *(.rel.rodata) }
- .rela.rodata : { *(.rela.rodata) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.bss : { *(.rel.bss) }
- .rela.bss : { *(.rela.bss) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .init : { *(.init) } =0
- .plt : { *(.plt) }
- .text :
- {
- *(.text)
- *(.rodata)
- *(.rodata1)
- *(.got1)
- }
- .fini : { *(.fini) } =0
- .ctors : { *(.ctors) }
- .dtors : { *(.dtors) }
- _etext = .;
- PROVIDE (etext = .);
- /* Read-write section, merged into data segment: */
- . = (. + 0x0FFF) & 0xFFFFF000;
- .data :
- {
- *(.data)
- *(.data1)
- *(.sdata)
- *(.sdata2)
- *(.got.plt) *(.got)
- *(.dynamic)
- CONSTRUCTORS
- }
- _edata = .;
- PROVIDE (edata = .);
- __bss_start = .;
- .bss :
- {
- *(.sbss) *(.scommon)
- *(.dynbss)
- *(.bss)
- *(COMMON)
- }
- _end = . ;
- PROVIDE (end = .);
-}
-
+++ /dev/null
-/*
- * Copyright (c) 1997 Paul Mackerras <paulus@cs.anu.edu.au>
- * Initial Power Macintosh COFF version.
- * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
- * Modifications for an ELF-based IBM evaluation board version.
- *
- * Module name: main.c
- *
- * Description:
- * This module does most of the real work for the boot loader. It
- * checks the variables holding the absolute start address and size
- * of the Linux kernel "image" and initial RAM disk "initrd" sections
- * and if they are present, moves them to their "proper" locations.
- *
- * For the Linux kernel, "proper" is physical address 0x00000000.
- * For the RAM disk, "proper" is the image's size below the top
- * of physical memory. The Linux kernel may be in either raw
- * binary form or compressed with GNU zip (aka gzip).
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- */
-
-#include <asm/board.h>
-
-#include "../coffboot/nonstdio.h"
-#include "../coffboot/zlib.h"
-#include "irSect.h"
-
-
-/* Preprocessor Defines */
-
-/*
- * Location of the IBM boot ROM function pointer address for retrieving
- * the board information structure.
- */
-
-#define BOARD_INFO_VECTOR 0xFFFE0B50
-
-#define RAM_SIZE (4 * 1024 * 1024)
-
-#define RAM_PBASE 0x00000000
-#define RAM_PEND (RAM_PBASE + RAM_SIZE)
-
-#define RAM_VBASE 0xC0000000
-#define RAM_VEND (RAM_VBASE + RAM_SIZE)
-
-#define RAM_START RAM_PBASE
-#define RAM_END RAM_PEND
-#define RAM_FREE (imageSect_start + imageSect_size + initrdSect_size)
-
-#define PROG_START RAM_START
-
-
-/* Function Macros */
-
-#define ALIGN_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1))
-
-
-/* Global Variables */
-
-/* Needed by zalloc and zfree for allocating memory */
-
-char *avail_ram; /* Indicates start of RAM available for heap */
-char *end_avail; /* Indicates end of RAM available for heap */
-
-bd_t board_info;
-
-/*
- * XXX - Until either the IBM boot ROM provides a way of passing arguments to
- * the program it launches or until I/O is working in the boot loader,
- * this is a good spot to pass in command line arguments to the kernel
- * (e.g. console=tty0).
- */
-
-static char *cmdline = "";
-
-
-/* Function Prototypes */
-
-void *zalloc(void *x, unsigned items, unsigned size);
-void zfree(void *x, void *addr, unsigned nb);
-
-void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp);
-
-void printf () {}
-void pause () {}
-void exit () {}
-
-
-void start(void)
-{
- void *options;
- int ns, oh, i;
- unsigned long sa, len;
- void *dst;
- unsigned char *im;
- unsigned long initrd_start, initrd_size;
- bd_t *(*get_board_info)(void) =
- (bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR);
- bd_t *bip = NULL;
-
- if ((bip = get_board_info()) != NULL)
- memcpy(&board_info, bip, sizeof(bd_t));
-
- /* setup_bats(RAM_START); */
-
- /* Init RAM disk (initrd) section */
-
- if (initrdSect_start != 0 && (initrd_size = initrdSect_size) != 0) {
- initrd_start = (RAM_END - initrd_size) & ~0xFFF;
-
- printf("Initial RAM disk at 0x%08x (%u bytes)\n",
- initrd_start, initrd_size);
-
- memcpy((char *)initrd_start,
- (char *)(initrdSect_start),
- initrdSect_size);
-
- end_avail = (char *)initrd_start;
- } else {
- initrd_start = initrd_size = 0;
- end_avail = (char *)RAM_END;
- }
-
- /* Linux kernel image section */
-
- im = (unsigned char *)(imageSect_start);
- len = imageSect_size;
- dst = (void *)PROG_START;
-
- /* Check for the gzip archive magic numbers */
-
- if (im[0] == 0x1f && im[1] == 0x8b) {
-
- /* The gunzip routine needs everything nice and aligned */
-
- void *cp = (void *)ALIGN_UP(RAM_FREE, 8);
- avail_ram = (void *)(cp + ALIGN_UP(len, 8));
- memcpy(cp, im, len);
-
- /* I'm not sure what the 0x200000 parameter is for, but it works. */
-
- gunzip(dst, 0x200000, cp, (int *)&len);
- } else {
- memmove(dst, im, len);
- }
-
- flush_cache(dst, len);
-
- sa = (unsigned long)dst;
-
- (*(void (*)())sa)(&board_info,
- initrd_start,
- initrd_start + initrd_size,
- cmdline,
- cmdline + strlen(cmdline));
-
- pause();
-}
-
-void *zalloc(void *x, unsigned items, unsigned size)
-{
- void *p = avail_ram;
-
- size *= items;
- size = ALIGN_UP(size, 8);
- avail_ram += size;
- if (avail_ram > end_avail) {
- printf("oops... out of memory\n");
- pause();
- }
- return p;
-}
-
-void zfree(void *x, void *addr, unsigned nb)
-{
-
-}
-
-#define HEAD_CRC 2
-#define EXTRA_FIELD 4
-#define ORIG_NAME 8
-#define COMMENT 0x10
-#define RESERVED 0xe0
-
-#define DEFLATED 8
-
-void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
-{
- z_stream s;
- int r, i, flags;
-
- /* skip header */
- i = 10;
- flags = src[3];
- if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
- printf("bad gzipped data\n");
- exit();
- }
- if ((flags & EXTRA_FIELD) != 0)
- i = 12 + src[10] + (src[11] << 8);
- if ((flags & ORIG_NAME) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & COMMENT) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & HEAD_CRC) != 0)
- i += 2;
- if (i >= *lenp) {
- printf("gunzip: ran out of data in header\n");
- exit();
- }
- printf("done 1\n");
- s.zalloc = zalloc;
- s.zfree = zfree;
- r = inflateInit2(&s, -MAX_WBITS);
- if (r != Z_OK) {
- printf("inflateInit2 returned %d\n", r);
- exit();
- }
- s.next_in = src + i;
- s.avail_in = *lenp - i;
- s.next_out = dst;
- s.avail_out = dstlen;
- printf("doing inflate\n");
- r = inflate(&s, Z_FINISH);
- printf("done inflate\n");
- if (r != Z_OK && r != Z_STREAM_END) {
- printf("inflate returned %d\n", r);
- exit();
- }
- *lenp = s.next_out - (unsigned char *) dst;
- printf("doing end\n");
- inflateEnd(&s);
-}
+++ /dev/null
-/*
- * Copyright (C) Paul Mackerras 1997.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include "../kernel/ppc_asm.tmpl"
-
- .text
-
-/*
- * Flush the dcache and invalidate the icache for a range of addresses.
- *
- * flush_cache(addr, len)
- */
- .global flush_cache
-flush_cache:
- mfpvr r5 # Get processor version register
- extrwi r5,r5,16,0 # Get the version bits
- cmpwi cr0,r5,0x0020 # Is this a 403-based processor?
- beq 1f # Yes, it is
- li r5,32 # It is not a 403, set to 32 bytes
- addi r4,r4,32-1 # len += line_size - 1
- srwi. r4,r4,5 # Convert from bytes to lines
- b 2f
-1: li r5,16 # It is a 403, set to 16 bytes
- addi r4,r4,16-1 # len += line_size - 1
- srwi. r4,r4,4 # Convert from bytes to lines
-2: mtctr r4 # Set-up the counter register
- beqlr # If it is 0, we are done
-3: dcbf r0,r3 # Flush and invalidate the data line
- icbi r0,r3 # Invalidate the instruction line
- add r3,r3,r5 # Move to the next line
- bdnz 3b # Are we done yet?
- sync
- isync
- blr # Return to the caller
+++ /dev/null
-#!/usr/bin/perl
-
-#
-# Copyright (c) 1998-1999 TiVo, Inc.
-# All rights reserved.
-#
-# Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
-# Major syntactic and usability rework.
-#
-# Module name: mkevimg
-#
-# Description:
-# Converts an ELF output file from the linker into the format used by
-# the IBM evaluation board ROM Monitor to load programs from a host
-# onto the evaluation board. The ELF file must be an otherwise execut-
-# able file (with the text and data addresses bound at link time) and
-# have space reserved after the entry point for the load information
-# block:
-#
-# typedef struct boot_block {
-# unsigned long magic; 0x0052504F
-# unsigned long dest; Target address of the image
-# unsigned long num_512blocks; Size, rounded-up, in 512 byte blocks
-# unsigned long debug_flag; Run the debugger or image after load
-# unsigned long entry_point; The image address to jump to after load
-# unsigned long reserved[3];
-# } boot_block_t;
-#
-#
-
-use File::Basename;
-use Getopt::Std;
-
-#
-# usage()
-#
-# Description:
-# This routine prints out the proper command line usage for this program
-#
-# Input(s):
-# status - Flag determining what usage information will be printed and what
-# the exit status of the program will be after the information is
-# printed.
-#
-# Output(s):
-# N/A
-#
-# Returns:
-# This subroutine does not return.
-#
-
-sub usage {
- my($status);
- $status = $_[0];
-
- printf("Usage: %s [-hlvV] <ELF input file> <Evaluation board output file>\n",
- $program);
-
- if ($status != 0) {
- printf("Try `%s -h' for more information.\n", $program);
- }
-
- if ($status != 1) {
- print(" -h Print out this message and exit.\n");
- print(" -l Linux mode; if present, copy 'image' and 'initrd' sections.\n");
- print(" -v Verbose. Print out lots of ELF information.\n");
- print(" -V Print out version information and exit.\n");
- }
-
- exit($status);
-}
-
-#
-# version()
-#
-# Description:
-# This routine prints out program version information
-#
-# Input(s):
-# N/A
-#
-# Output(s):
-# N/A
-#
-# Returns:
-# This subroutine does not return.
-#
-
-sub version {
- print("mkevimg Version 1.1.0\n");
- print("Copyright (c) 1998-1999 TiVo, Inc.\n");
- print("Copyright (c) 1999 Grant Erickson <grant\@lcse.umn.edu>\n");
-
- exit (0);
-}
-
-#
-# file_check()
-#
-# Description:
-# This routine checks an input file to ensure that it exists, is a
-# regular file, and is readable.
-#
-# Input(s):
-# file - Input file to be checked.
-#
-# Output(s):
-# N/A
-#
-# Returns:
-# 0 if the file exists, is a regular file, and is readable, otherwise -1.
-#
-
-sub file_check {
- my($file);
- $file = $_[0];
-
- if (!(-e $file)) {
- printf("The file \"%s\" does not exist.\n", $file);
- return (-1);
- } elsif (!(-f $file)) {
- printf("The file \"%s\" is not a regular file.\n", $file);
- return (-1);
- } elsif (!(-r $file)) {
- printf("The file \"%s\" is not readable.\n", $file);
- return (-1);
- }
-
- return (0);
-}
-
-#
-# decode_options()
-#
-# Description:
-# This routine steps through the command-line arguments, parsing out
-# recognzied options.
-#
-# Input(s):
-# N/A
-#
-# Output(s):
-# N/A
-#
-# Returns:
-# N/A
-#
-
-sub decode_options {
-
- if (!getopts("hlvV")) {
- usage(1);
- }
-
- if ($opt_h) {
- usage(0);
- }
-
- if ($opt_l) {
- $linux = 1;
- }
-
- if ($opt_V) {
- version();
- exit (0);
- }
-
- if ($opt_v) {
- $verbose = 1;
- }
-
- if (!($ifile = shift(@ARGV))) {
- usage(1);
- }
-
- if (!($ofile = shift(@ARGV))) {
- usage (1);
- }
-
- if (file_check($ifile)) {
- exit(1);
- }
-
-}
-
-#
-# ELF file and section header field numbers
-#
-
-require 'elf.pl';
-
-#
-# Main program body
-#
-
-{
- $program = basename($0);
-
- decode_options();
-
- open(ELF, "<$ifile") || die "Cannot open input file";
-
- $ifilesize = (-s $ifile);
-
- if ($verbose) {
- print("Output file: $ofile\n");
- print("Input file: $ifile, $ifilesize bytes.\n");
- }
-
- if (read(ELF, $ibuf, $ifilesize) != $ifilesize) {
- print("Failed to read input file!\n");
- exit(1);
- }
-
- #
- # Parse ELF header
- #
-
- @eh = unpack("a16n2N5n6", $ibuf);
-
- #
- # Make sure this is actually a PowerPC ELF file.
- #
-
- if (substr($eh[$e_ident], 0, 4) ne "\177ELF") {
- printf("The file \"%s\" is not an ELF file.\n", $ifile);
- exit (1);
- } elsif ($eh[$e_machine] != 20) {
- printf("The file \"%s\" is not a PowerPC ELF file.\n", $ifile);
- exit (1);
- }
-
- if ($verbose) {
- print("File header:\n");
- printf(" Identifier: %s\n", $eh[$e_ident]);
- printf(" Type: %d\n", $eh[$e_type]);
- printf(" Machine: %d\n", $eh[$e_machine]);
- printf(" Version: %d\n", $eh[$e_version]);
- printf(" Entry point: 0x%08x\n", $eh[$e_entry]);
- printf(" Program header offset: 0x%x\n", $eh[$e_phoff]);
- printf(" Section header offset: 0x%x\n", $eh[$e_shoff]);
- printf(" Flags: 0x%08x\n", $eh[$e_flags]);
- printf(" Header size: %d\n", $eh[$e_ehsize]);
- printf(" Program entry size: %d\n", $eh[$e_phentsize]);
- printf(" Program table entries: %d\n", $eh[$e_phnum]);
- printf(" Section header size: %d\n", $eh[$e_shentsize]);
- printf(" Section table entries: %d\n", $eh[$e_shnum]);
- printf(" String table section: %d\n", $eh[$e_shstrndx]);
- }
-
- #
- # Find the section header for the string table.
- #
-
- $strtable_section_offset = $eh[$e_shoff] +
- $eh[$e_shstrndx] * $eh[$e_shentsize];
-
- if ($verbose) {
- printf("String table section header offset: 0x%x\n",
- $strtable_section_offset);
- }
-
- #
- # Find the start of the string table.
- #
-
- @strh = unpack("N10", substr($ibuf, $strtable_section_offset,
- $eh[$e_shentsize]));
-
- if ($verbose) {
- printf("Section name strings start at: 0x%x, %d bytes.\n",
- $strh[$sh_offset], $strh[$sh_size]);
- }
-
- $names = substr($ibuf, $strh[$sh_offset], $strh[$sh_size]);
-
- # Grab each section header and find '.text' and '.bss' sections in
- # particular.
-
- if ($verbose) {
- print("Section headers:\n");
- print("Idx Name Size Address File off Algn\n");
- print("--- ------------------------ -------- -------- -------- ----\n");
- }
-
- $off = $eh[$e_shoff];
-
- for($i = 0; $i < $eh[$e_shnum]; $i++, $off += $eh[$e_shentsize]) {
- @sh = unpack("N10", substr($ibuf, $off, $eh[$e_shentsize]));
-
- # Take the first section name from the array returned by split.
-
- ($name) = split(/\000/, substr($names, $sh[$sh_name]));
-
- if ($verbose) {
- printf("%3d %-24s %8x %08x %08x %4d\n",
- $i, $name, $sh[$sh_size], $sh[$sh_addr],
- $sh[$sh_offset], $sh[$sh_addralign]);
- }
-
- # Attempt to find the .text and .bss sections
-
- if ($name =~ /^\.bss$/) {
- ($bss_addr, $bss_offset, $bss_size) =
- ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
-
- } elsif ($name =~ /^\.text$/) {
- ($text_addr, $text_offset, $text_size) =
- ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
-
- } elsif ($linux && ($name =~ /^\image$/)) {
- $image_found = 1;
-
- ($image_addr, $image_offset, $image_size) =
- ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
-
- } elsif ($linux && ($name =~ /^\initrd$/)) {
- $initrd_found = 1;
-
- ($initrd_addr, $initrd_offset, $initrd_size) =
- ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
-
- }
- }
-
- printf("Text section - Address: 0x%08x, Size: 0x%08x\n",
- $text_addr, $text_size);
- printf("Bss section - Address: 0x%08x, Size: 0x%08x\n",
- $bss_addr, $bss_size);
-
- if ($linux) {
- if ($image_found) {
- printf("Image section - Address: 0x%08x, Size: 0x%08x\n",
- $image_addr, $image_size);
- }
-
- if ($initrd_found) {
- printf("Initrd section - Address: 0x%08x, Size: 0x%08x\n",
- $initrd_addr, $initrd_size);
- }
- }
-
- #
- # Open output file
- #
-
- open(BOOT, ">$ofile") || die "Cannot open output file";
-
- #
- # Compute image size
- #
-
- $output_size = $bss_offset - $text_offset + $bss_size;
-
- if ($linux && $image_found) {
- $output_size += $image_size;
- }
-
- if ($linux && $initrd_found) {
- $output_size += $initrd_size;
- }
-
- $num_blocks = $output_size / 512 + 1;
-
- #
- # Write IBM PowerPC evaluation board boot_block_t header
- #
-
- $header = pack("H8N7", "0052504f", $text_addr, $num_blocks, 0,
- $text_addr, 0, 0, 0);
-
- $bytes = length($header);
-
- if (($resid = syswrite(BOOT, $header, $bytes)) != $bytes) {
- die("Could not write boot image header to output file.");
- }
-
- printf("Entry point = 0x%08x\n", $text_addr);
- printf("Image size = 0x%08x (%d bytes) (%d blocks).\n",
- $output_size, $output_size, $num_blocks);
-
- #
- # Write image starting after ELF and program headers and
- # continuing to beginning of bss
- #
-
- $bytes = $bss_offset - $text_offset + $bss_size;
-
- if (($resid = syswrite(BOOT, $ibuf, $bytes, $text_offset)) != $bytes) {
- die("Could not write boot image to output file.\n");
- }
-
- #
- # If configured, write out the image and initrd sections as well
- #
-
- if ($linux) {
- if ($image_found) {
- $bytes = $image_size;
- if (($resid = syswrite(BOOT, $ibuf, $bytes, $image_offset)) != $bytes) {
- die("Could not write boot image to output file.\n");
- }
- }
-
- if ($initrd_found) {
- $bytes = $initrd_size;
- if (($resid = syswrite(BOOT, $ibuf, $bytes, $initrd_offset)) != $bytes) {
- die("Could not write boot image to output file.\n");
- }
- }
- }
-
- #
- # Pad to a multiple of 512 bytes
- #
-
- $pad_size = 512 - (length($header) + $output_size) % 512;
-
- if ($verbose) {
- print("Padding boot image by an additional $pad_size bytes.\n");
- }
-
- $pad_string = pack(("H8","deadbeef") x 128);
-
- syswrite(BOOT, $pad_string, $pad_size) or
- die "Could not pad boot image in output file.\n";
-
- #
- # Clean-up and leave
- #
-
- close(BOOT);
-
- print("\nBoot image file \"$ofile\" built successfully.\n\n");
-
- exit(0);
-}
+++ /dev/null
-#!/usr/bin/perl
-#
-# Copyright (c) 1998-1999 TiVo, Inc.
-# Original ELF parsing code.
-#
-# Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
-# Original code from 'mkevimg'.
-#
-# Module name: mkirimg
-#
-# Description:
-# Reads an ELF file and assigns global variables 'imageSect_start',
-# 'imageSect_size', 'initrdSect_start', and 'initrdSect_size' from
-# the "image" and "initrd" section header information. It then
-# rewrites the input ELF file with assigned globals to an output
-# file.
-#
-# An input file, "irSectStart.txt" has the memory address of
-# 'irSectStart'. The irSectStart memory address is used to find
-# the global variables in the ".data" section of the ELF file.
-# The 'irSectStart' and the above global variables are defined
-# in "irSect.c".
-#
-#
-
-use File::Basename;
-use Getopt::Std;
-
-#
-# usage()
-#
-# Description:
-# This routine prints out the proper command line usage for this program
-#
-# Input(s):
-# status - Flag determining what usage information will be printed and what
-# the exit status of the program will be after the information is
-# printed.
-#
-# Output(s):
-# N/A
-#
-# Returns:
-# This subroutine does not return.
-#
-
-sub usage {
- my($status);
- $status = $_[0];
-
- printf("Usage: %s [-hvV] <ELF input file> <Evaluation board output file> <irSectStart.txt file>\n",
- $program);
-
- if ($status != 0) {
- printf("Try `%s -h' for more information.\n", $program);
- }
-
- if ($status != 1) {
- print(" -h Print out this message and exit.\n");
- print(" -v Verbose. Print out lots of ELF information.\n");
- print(" -V Print out version information and exit.\n");
- }
-
- exit($status);
-}
-
-#
-# version()
-#
-# Description:
-# This routine prints out program version information
-#
-# Input(s):
-# N/A
-#
-# Output(s):
-# N/A
-#
-# Returns:
-# This subroutine does not return.
-#
-
-sub version {
- print("mkirimg Version 1.1.0\n");
- print("Copyright (c) 1998-1999 TiVo, Inc.\n");
- print("Copyright (c) 1999 Grant Erickson <grant\@lcse.umn.edu>\n");
-
- exit (0);
-}
-
-#
-# file_check()
-#
-# Description:
-# This routine checks an input file to ensure that it exists, is a
-# regular file, and is readable.
-#
-# Input(s):
-# file - Input file to be checked.
-#
-# Output(s):
-# N/A
-#
-# Returns:
-# 0 if the file exists, is a regular file, and is readable, otherwise -1.
-#
-
-sub file_check {
- my($file);
- $file = $_[0];
-
- if (!(-e $file)) {
- printf("The file \"%s\" does not exist.\n", $file);
- return (-1);
- } elsif (!(-f $file)) {
- printf("The file \"%s\" is not a regular file.\n", $file);
- return (-1);
- } elsif (!(-r $file)) {
- printf("The file \"%s\" is not readable.\n", $file);
- return (-1);
- }
-
- return (0);
-}
-
-#
-# decode_options()
-#
-# Description:
-# This routine steps through the command-line arguments, parsing out
-# recognzied options.
-#
-# Input(s):
-# N/A
-#
-# Output(s):
-# N/A
-#
-# Returns:
-# N/A
-#
-
-sub decode_options {
-
- if (!getopts("hvV")) {
- usage(1);
- }
-
- if ($opt_h) {
- usage(0);
- }
-
- if ($opt_V) {
- version();
- exit (0);
- }
-
- if ($opt_v) {
- $verbose = 1;
- }
-
- if (!($ElfFile = shift(@ARGV))) {
- usage(1);
- }
-
- if (!($OutputFile = shift(@ARGV))) {
- usage (1);
- }
-
- if (!($IrFile = shift(@ARGV))) {
- usage (1);
- }
-
- if (file_check($ElfFile)) {
- exit(1);
- }
-
- if (file_check($IrFile)) {
- exit(1);
- }
-}
-
-#
-# ELF file and section header field numbers
-#
-
-require 'elf.pl';
-
-#
-# Main program body
-#
-
-{
- $program = basename($0);
- decode_options();
-
- open(ELF, "<$ElfFile") || die "Cannot open input file";
- open(OUTPUT, ">$OutputFile") || die "Cannot open output file";
- open(IR, "$IrFile") || die "Cannot open input file";
-
- $ElfFilesize = (-s $ElfFile);
-
- if (read(ELF, $ibuf, $ElfFilesize) != $ElfFilesize) {
- print("Failed to read ELF input file!\n");
- exit(1);
- }
-
- if (read(IR, $irbuf, 8) != 8) {
- print("Failed to read Ir input file!\n");
- exit(1);
- }
-
- #
- # Parse ELF header
- #
-
- @eh = unpack("a16n2N5n6", $ibuf);
-
- #
- # Make sure this is actually a PowerPC ELF file.
- #
-
- if (substr($eh[$e_ident], 0, 4) ne "\177ELF") {
- printf("The file \"%s\" is not an ELF file.\n", $ElfFile);
- exit (1);
- } elsif ($eh[$e_machine] != 20) {
- printf("The file \"%s\" is not a PowerPC ELF file.\n", $ElfFile);
- exit (1);
- }
-
- #
- # Find the section header for the string table.
- #
-
- $strtable_section_offset = $eh[$e_shoff] +
-
- $eh[$e_shstrndx] * $eh[$e_shentsize];
-
- if ($verbose) {
- printf("String table section header offset: 0x%x\n",
- $strtable_section_offset);
- }
-
- #
- # Find the start of the string table.
- #
-
- @strh = unpack("N10", substr($ibuf, $strtable_section_offset,
- $eh[$e_shentsize]));
-
- if ($verbose) {
- printf("Section name strings start at: 0x%x, %d bytes.\n",
- $strh[$sh_offset], $strh[$sh_size]);
- }
-
- $names = substr($ibuf, $strh[$sh_offset], $strh[$sh_size]);
-
- # Grab each section header and find '.data', 'image', and
- # 'initrd' sections in particular.
-
- $off = $eh[$e_shoff];
- $imageFound = 0;
- $initrdFound = 0;
-
- for($i = 0; $i < $eh[$e_shnum]; $i++, $off += $eh[$e_shentsize]) {
- @sh = unpack("N10", substr($ibuf, $off, $eh[$e_shentsize]));
-
- # Take the first section name from the array returned by split.
-
- ($name) = split(/\000/, substr($names, $sh[$sh_name]));
-
- # Attempt to find the .data, image, and initrd sections
-
- if ($name =~ /^\image$/) {
- ($image_addr, $image_offset, $image_size) =
- ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
- $imageFound = 1;
-
- } elsif ($name =~ /^\initrd$/) {
- ($initrd_addr, $initrd_offset, $initrd_size) =
- ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
- $initrdFound = 1;
-
- } elsif ($name =~ /^\.data$/) {
- ($data_addr, $data_offset, $data_size) =
- ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
-
- } elsif ($name =~ /^\.bss$/) {
- ($bss_addr, $bss_offset, $bss_size) =
- ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
-
- }
- }
-
- if ($verbose) {
- printf("Data section - Address: 0x%08x, Size: 0x%08x, File Offset 0x%08x\n",
- $data_addr, $data_size, $data_offset);
- printf("Bss section - Address: 0x%08x, Size: 0x%08x, File Offset 0x%08x\n",
- $bss_addr, $bss_size, $bss_offset);
- }
-
- if ($verbose) {
- if ($imageFound) {
- printf("Image section - Address: 0x%08x, Size: 0x%08x\n",
- $image_addr, $image_size);
- } else {
- printf("Image section not found in file: $ElfFile\n");
- }
-
- if ($initrdFound) {
- printf("Initrd section - Address: 0x%08x, Size: 0x%08x\n",
- $initrd_addr, $initrd_size);
- } else {
- printf("Initrd section not found in file: $ElfFile\n");
- }
- }
-
- # get file offset of irSectStart
-
- $irSectStartoffset = hex ($irbuf);
-
- if ($verbose) {
- printf("irSectStartOffset Address: 0x%08x\n", $irSectStartoffset);
- }
-
- # get the offset of global variables
-
- $initialOffset = ($irSectStartoffset - $data_addr) + $data_offset + 4;
-
- # write modified values to OUTPUT file
-
- syswrite(OUTPUT, $ibuf, $initialOffset);
-
- if ($imageFound) {
- $testN = pack ("N2", $bss_addr + $bss_size, $image_size);
- syswrite(OUTPUT, $testN, length($testN));
- printf("Updated symbol \"imageSect_start\" to 0x%08x\n",
- $bss_addr + $bss_size);
- printf("Updated symbol \"imageSect_size\" to 0x%08x\n", $image_size);
- } else {
- syswrite(OUTPUT, $ibuf, 8, $initialOffset);
- }
-
- if ($initrdFound) {
- $testN = pack ("N2", $bss_addr + $bss_size + $image_size, $initrd_size);
- syswrite(OUTPUT, $testN, length($testN));
- printf("Updated symbol \"initrdSect_start\" to 0x%08x\n",
- $bss_addr + $bss_size + $image_size);
- printf("Updated symbol \"initrdSect_size\" to 0x%08x\n", $initrd_size);
- } else {
- syswrite(OUTPUT, $ibuf,8, $initialOffset + 8);
- }
-
- syswrite(OUTPUT, $ibuf, $ElfFilesize - ($initialOffset + 16),
- $initialOffset + 16);
-
- #
- # Clean-up and leave
- #
-
- close (ELF);
- close (OUTPUT);
- close (IR);
-
- exit (0);
-}
-
static int set_rtc_time(unsigned long nowtime)
{
- extern int abs (int);
int retval = 0;
int real_seconds, real_minutes, cmos_minutes;
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
CONFIG_MINIX_FS=m
+CONFIG_VXFS_FS=m
# CONFIG_NTFS_FS is not set
# CONFIG_NTFS_RW is not set
CONFIG_HPFS_FS=m
#
CONFIG_USB_IBMCAM=m
CONFIG_USB_OV511=m
+CONFIG_USB_PWC=m
CONFIG_USB_DSBR=m
CONFIG_USB_DABUSB=m
-/* $Id: pci_iommu.c,v 1.13 2001/03/14 08:42:38 davem Exp $
+/* $Id: pci_iommu.c,v 1.14 2001/05/23 03:06:51 davem Exp $
* pci_iommu.c: UltraSparc PCI controller IOM/STC support.
*
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
static iopte_t *alloc_streaming_cluster(struct pci_iommu *iommu, unsigned long npages)
{
- iopte_t *iopte, *limit;
+ iopte_t *iopte, *limit, *first;
unsigned long cnum, ent, flush_point;
cnum = 0;
iopte += ((ent = iommu->alloc_info[cnum].next) << cnum);
flush_point = iommu->alloc_info[cnum].flush;
+ first = iopte;
for (;;) {
if (iopte_val(*iopte) == 0UL) {
if ((iopte + (1 << cnum)) >= limit)
}
if (ent == flush_point)
__iommu_flushall(iommu);
+ if (iopte == first)
+ goto bad;
}
/* I've got your streaming cluster right here buddy boy... */
return iopte;
+
+bad:
+ printk(KERN_EMERG "pci_iommu: alloc_streaming_cluster of npages(%ld) failed!\n",
+ npages);
+ return NULL;
}
static void free_streaming_cluster(struct pci_iommu *iommu, dma_addr_t base,
spin_lock_irqsave(&iommu->lock, flags);
base = alloc_streaming_cluster(iommu, npages);
+ if (base == NULL)
+ goto bad;
bus_addr = (iommu->page_table_map_base +
((base - iommu->page_table) << PAGE_SHIFT));
ret = bus_addr | (oaddr & ~PAGE_MASK);
spin_unlock_irqrestore(&iommu->lock, flags);
return ret;
+
+bad:
+ spin_unlock_irqrestore(&iommu->lock, flags);
+ BUG();
+ return 0;
}
/* Unmap a single streaming mode DMA translation. */
spin_lock_irqsave(&iommu->lock, flags);
base = alloc_streaming_cluster(iommu, npages);
+ if (base == NULL)
+ goto bad;
dma_base = iommu->page_table_map_base + ((base - iommu->page_table) << PAGE_SHIFT);
/* Step 3: Normalize DMA addresses. */
spin_unlock_irqrestore(&iommu->lock, flags);
return used;
+
+bad:
+ spin_unlock_irqrestore(&iommu->lock, flags);
+ BUG();
+ return 0;
}
/* Unmap a set of streaming mode DMA translations. */
-/* $Id: sbus.c,v 1.13 2001/02/13 01:16:44 davem Exp $
+/* $Id: sbus.c,v 1.14 2001/05/23 03:06:51 davem Exp $
* sbus.c: UltraSparc SBUS controller support.
*
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
static iopte_t *alloc_streaming_cluster(struct sbus_iommu *iommu, unsigned long npages)
{
- iopte_t *iopte, *limit;
+ iopte_t *iopte, *limit, *first;
unsigned long cnum, ent, flush_point;
cnum = 0;
iopte += ((ent = iommu->alloc_info[cnum].next) << cnum);
flush_point = iommu->alloc_info[cnum].flush;
+ first = iopte;
for (;;) {
if (iopte_val(*iopte) == 0UL) {
if ((iopte + (1 << cnum)) >= limit)
}
if (ent == flush_point)
__iommu_flushall(iommu);
+ if (iopte == first)
+ goto bad;
}
/* I've got your streaming cluster right here buddy boy... */
return iopte;
+
+bad:
+ printk(KERN_EMERG "sbus: alloc_streaming_cluster of npages(%ld) failed!\n",
+ npages);
+ return NULL;
}
static void free_streaming_cluster(struct sbus_iommu *iommu, u32 base, unsigned long npages)
spin_lock_irqsave(&iommu->lock, flags);
npages = size >> PAGE_SHIFT;
iopte = alloc_streaming_cluster(iommu, npages);
+ if (iopte == NULL)
+ goto bad;
dma_base = MAP_BASE + ((iopte - iommu->page_table) << PAGE_SHIFT);
npages = size >> PAGE_SHIFT;
iopte_bits = IOPTE_VALID | IOPTE_STBUF | IOPTE_CACHE;
spin_unlock_irqrestore(&iommu->lock, flags);
return (dma_base | offset);
+
+bad:
+ spin_unlock_irqrestore(&iommu->lock, flags);
+ BUG();
+ return 0;
}
void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size, int direction)
spin_lock_irqsave(&iommu->lock, flags);
iopte = alloc_streaming_cluster(iommu, npages);
+ if (iopte == NULL)
+ goto bad;
dma_base = MAP_BASE + ((iopte - iommu->page_table) << PAGE_SHIFT);
/* Normalize DVMA addresses. */
spin_unlock_irqrestore(&iommu->lock, flags);
return used;
+
+bad:
+ spin_unlock_irqrestore(&iommu->lock, flags);
+ BUG();
+ return 0;
}
void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int direction)
break;
}
if(ending != -1) {
- spin_lock_irqsave(io_request_lock, flags);
+ spin_lock_irqsave(&io_request_lock, flags);
end_request(ending);
do_ps2esdi_request(BLK_DEFAULT_QUEUE(MAJOR_NR));
- spin_unlock_irqrestore(io_request_lock, flags);
+ spin_unlock_irqrestore(&io_request_lock, flags);
}
} /* handle interrupts */
void cleanup_module(void)
{
- int partition,dev,start;
-
devfs_unregister_blkdev(MAJOR_NR, "xd");
xd_done();
devfs_unregister (devfs_handle);
return (0);
}
/*==========================================================================*/
-#endif 00000
+#endif
/*==========================================================================*/
static int ResponseInfo(void)
{
/*
* Shut off the timer.
*/
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
tco_timer_stop ();
timer_alive = 0;
+#endif
return 0;
}
extern int rtc_DP8570A_init(void);
extern int rtc_MK48T08_init(void);
extern int ds1286_init(void);
-extern int radio_init(void);
extern int pmu_device_init(void);
extern int tosh_init(void);
#ifdef CONFIG_SGI_DS1286
ds1286_init();
#endif
-#ifdef CONFIG_MISC_RADIO
- radio_init();
-#endif
#ifdef CONFIG_PMAC_PBOOK
pmu_device_init();
#endif
char *ret;
ret = kmalloc(6, GFP_KERNEL);
+ if(ret == NULL)
+ return NULL;
while((count < 3) && (!found)) {
outb_p(0x80, current_readport + 2);
ten = send_command(0x82);
hund = send_command(0x83);
minor = send_command(0x84);
- }
-
- if (found)
sprintf(ret, "%c.%c%c%c", one, ten, hund, minor);
+ }
else
sprintf(ret, "ERROR");
static void __exit pcwatchdog_exit(void)
{
+ misc_deregister(&pcwd_miscdev);
/* Disable the board */
if (revision == PCWD_REVISION_C) {
outb_p(0xA5, current_readport + 3);
outb_p(0xA5, current_readport + 3);
}
- misc_deregister(&pcwd_miscdev);
if (supports_temp)
misc_deregister(&temp_miscdev);
d = (struct dma_iso_ctx *)kmalloc(sizeof(struct dma_iso_ctx),
GFP_KERNEL);
- memset(d, 0, sizeof(struct dma_iso_ctx));
-
if (d==NULL) {
PRINT(KERN_ERR, ohci->id, "failed to allocate dma_iso_ctx");
return NULL;
}
+ memset(d, 0, sizeof(struct dma_iso_ctx));
+
d->ohci = (void *)ohci;
d->ctx = ctx;
d->channel = channel;
/*
- * $Id: capifs.c,v 1.14.6.5 2001/03/21 08:52:21 kai Exp $
- *
+ * $Id: capifs.c,v 1.14.6.7 2001/05/24 08:29:08 kai Exp $
+ *
* (c) Copyright 2000 by Carsten Paeth (calle@calle.de)
*
* Heavily based on devpts filesystem from H. Peter Anvin
- *
- * $Log: capifs.c,v $
- * Revision 1.14.6.5 2001/03/21 08:52:21 kai
- * merge from main branch: fix buffer for revision string (calle)
- *
- * Revision 1.14.6.4 2001/03/15 15:11:24 kai
- * *** empty log message ***
- *
- * Revision 1.14.6.3 2001/02/13 11:43:29 kai
- * more compatility changes for 2.2.19
- *
- * Revision 1.14.6.2 2001/02/10 14:41:20 kai
- * Changes from kernel tree
- *
- * Revision 1.14.6.1 2000/11/28 12:02:45 kai
- * MODULE_DEVICE_TABLE for 2.4
- *
- * Revision 1.14.2.1 2000/11/26 17:47:53 kai
- * added PCI_DEV_TABLE for 2.4
- *
- * Revision 1.14 2000/11/23 20:45:14 kai
- * fixed module_init/exit stuff
- * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
- *
- * Revision 1.13 2000/11/18 16:17:25 kai
- * change from 2.4 tree
- *
- * Revision 1.12 2000/11/01 14:05:02 calle
- * - use module_init/module_exit from linux/init.h.
- * - all static struct variables are initialized with "membername:" now.
- * - avm_cs.c, let it work with newer pcmcia-cs.
- *
- * Revision 1.11 2000/10/24 15:08:47 calle
- * Too much includes.
- *
- * Revision 1.10 2000/10/12 10:12:35 calle
- * Bugfix: second iput(inode) on umount, destroies a foreign inode.
- *
- * Revision 1.9 2000/08/20 07:30:13 keil
- * changes for 2.4
- *
- * Revision 1.8 2000/07/20 10:23:13 calle
- * Include isdn_compat.h for people that don't use -p option of std2kern.
- *
- * Revision 1.7 2000/06/18 16:09:54 keil
- * more changes for 2.4
- *
- * Revision 1.6 2000/04/03 13:29:25 calle
- * make Tim Waugh happy (module unload races in 2.3.99-pre3).
- * no real problem there, but now it is much cleaner ...
- *
- * Revision 1.5 2000/03/13 17:49:52 calle
- * make it running with 2.3.51.
- *
- * Revision 1.4 2000/03/08 17:06:33 calle
- * - changes for devfs and 2.3.49
- * - capifs now configurable (no need with devfs)
- * - New Middleware ioctl CAPI_NCCI_GETUNIT
- * - Middleware again tested with 2.2.14 and 2.3.49 (with and without devfs)
- *
- * Revision 1.3 2000/03/06 18:00:23 calle
- * - Middleware extention now working with 2.3.49 (capifs).
- * - Fixed typos in debug section of capi.c
- * - Bugfix: Makefile corrected for b1pcmcia.c
- *
- * Revision 1.2 2000/03/06 09:17:07 calle
- * - capifs: fileoperations now in inode (change for 2.3.49)
- * - Config.in: Middleware extention not a tristate, uups.
- *
- * Revision 1.1 2000/03/03 16:48:38 calle
- * - Added CAPI2.0 Middleware support (CONFIG_ISDN_CAPI)
- * It is now possible to create a connection with a CAPI2.0 applikation
- * and than to handle the data connection from /dev/capi/ (capifs) and also
- * using async or sync PPP on this connection.
- * The two major device number 190 and 191 are not confirmed yet,
- * but I want to save the code in cvs, before I go on.
- *
*
*/
MODULE_AUTHOR("Carsten Paeth <calle@calle.de>");
-static char *revision = "$Revision: 1.14.6.6 $";
+static char *revision = "$Revision: 1.14.6.7 $";
struct capifs_ncci {
struct inode *inode;
static int capifs_root_readdir(struct file *,void *,filldir_t);
static struct dentry *capifs_root_lookup(struct inode *,struct dentry *);
static int capifs_revalidate(struct dentry *, int);
+static struct inode *capifs_new_inode(struct super_block *sb);
static struct file_operations capifs_root_operations = {
read: generic_read_dir,
kfree(sbi->nccis);
kfree(sbi);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,51)
- MOD_DEC_USE_COUNT;
-#endif
}
static int capifs_statfs(struct super_block *sb, struct statfs *buf);
struct dentry * root;
struct capifs_sb_info *sbi;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,51)
- MOD_INC_USE_COUNT;
- lock_super(s);
-#endif
/* Super block already completed? */
if (s->s_root)
goto out;
mounts = s;
out: /* Success ... somebody else completed the super block for us. */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,51)
- unlock_super(s);
-#endif
return s;
fail:
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,51)
- unlock_super(s);
- MOD_DEC_USE_COUNT;
-#endif
return NULL;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,51)
-static int capifs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
-{
- struct statfs tmp;
-
- tmp.f_type = CAPIFS_SUPER_MAGIC;
- tmp.f_bsize = 1024;
- tmp.f_blocks = 0;
- tmp.f_bfree = 0;
- tmp.f_bavail = 0;
- tmp.f_files = 0;
- tmp.f_ffree = 0;
- tmp.f_namelen = NAME_MAX;
- return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
-}
-#else
static int capifs_statfs(struct super_block *sb, struct statfs *buf)
{
buf->f_type = CAPIFS_SUPER_MAGIC;
buf->f_namelen = NAME_MAX;
return 0;
}
-#endif
-static struct inode *capifs_new_inode(struct super_block *sb);
+static struct inode *capifs_new_inode(struct super_block *sb)
{
- inode = new_inode(sb);
+ struct inode *inode = new_inode(sb);
if (inode) {
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->i_blocks = 0;
return inode;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,51)
-static struct file_system_type capifs_fs_type = {
- "capifs",
- 0,
- capifs_read_super,
- NULL
-};
-#else
static DECLARE_FSTYPE(capifs_fs_type, "capifs", capifs_read_super, 0);
-#endif
void capifs_new_ncci(char type, unsigned int num, kdev_t device)
{
MOD_DEC_USE_COUNT;
return err;
}
-#ifdef MODULE
- printk(KERN_NOTICE "capifs: Rev %s: loaded\n", rev);
-#else
- printk(KERN_NOTICE "capifs: Rev %s: started\n", rev);
-#endif
+ printk(KERN_NOTICE "capifs: Rev %s\n", rev);
MOD_DEC_USE_COUNT;
return 0;
}
md_spin_unlock_irq(&conf->device_lock);
}
-static int raid1_map (mddev_t *mddev, kdev_t *rdev, unsigned long size)
+static int raid1_map (mddev_t *mddev, kdev_t *rdev)
{
raid1_conf_t *conf = mddev_to_conf(mddev);
int i, disks = MD_SB_DISKS;
bh_req = &r1_bh->bh_req;
memcpy(bh_req, bh, sizeof(*bh));
- bh_req->b_blocknr = bh->b_rsector / sectors;
+ bh_req->b_blocknr = bh->b_rsector;
bh_req->b_dev = mirror->dev;
bh_req->b_rdev = mirror->dev;
/* bh_req->b_rsector = bh->n_rsector; */
/*
* prepare mirrored mbh (fields ordered for max mem throughput):
*/
- mbh->b_blocknr = bh->b_rsector / sectors;
+ mbh->b_blocknr = bh->b_rsector;
mbh->b_dev = conf->mirrors[i].dev;
mbh->b_rdev = conf->mirrors[i].dev;
mbh->b_rsector = bh->b_rsector;
int disks = MD_SB_DISKS;
struct buffer_head *bhl, *mbh;
raid1_conf_t *conf;
- int sectors = bh->b_size >> 9;
conf = mddev_to_conf(mddev);
bhl = raid1_alloc_bh(conf, conf->raid_disks); /* don't really need this many */
mbh->b_blocknr = bh->b_blocknr;
mbh->b_dev = conf->mirrors[i].dev;
mbh->b_rdev = conf->mirrors[i].dev;
- mbh->b_rsector = bh->b_blocknr * sectors;
+ mbh->b_rsector = bh->b_blocknr;
mbh->b_state = (1<<BH_Req) | (1<<BH_Dirty) |
(1<<BH_Mapped) | (1<<BH_Lock);
atomic_set(&mbh->b_count, 1);
}
} else {
dev = bh->b_dev;
- raid1_map (mddev, &bh->b_dev, bh->b_size >> 9);
+ raid1_map (mddev, &bh->b_dev);
if (bh->b_dev == dev) {
printk (IO_ERROR, partition_name(bh->b_dev), bh->b_blocknr);
md_done_sync(mddev, bh->b_size>>9, 0);
printk (REDIRECT_SECTOR,
partition_name(bh->b_dev), bh->b_blocknr);
bh->b_rdev = bh->b_dev;
+ bh->b_rsector = bh->b_blocknr;
generic_make_request(READ, bh);
}
}
case READ:
case READA:
dev = bh->b_dev;
-
- raid1_map (mddev, &bh->b_dev, bh->b_size >> 9);
+ raid1_map (mddev, &bh->b_dev);
if (bh->b_dev == dev) {
printk (IO_ERROR, partition_name(bh->b_dev), bh->b_blocknr);
raid1_end_bh_io(r1_bh, 0);
printk (REDIRECT_SECTOR,
partition_name(bh->b_dev), bh->b_blocknr);
bh->b_rdev = bh->b_dev;
+ bh->b_rsector = bh->b_blocknr;
generic_make_request (r1_bh->cmd, bh);
}
break;
struct buffer_head *bh;
int bsize;
int disk;
+ int block_nr;
spin_lock_irq(&conf->segment_lock);
if (!sector_nr) {
r1_bh->cmd = SPECIAL;
bh = &r1_bh->bh_req;
- bh->b_blocknr = sector_nr;
+ block_nr = sector_nr;
bsize = 512;
- while (!(bh->b_blocknr & 1) && bsize < PAGE_SIZE
- && (bh->b_blocknr+2)*(bsize>>9) < (mddev->sb->size *2)) {
- bh->b_blocknr >>= 1;
+ while (!(block_nr & 1) && bsize < PAGE_SIZE
+ && (block_nr+2)*(bsize>>9) < (mddev->sb->size *2)) {
+ block_nr >>= 1;
bsize <<= 1;
}
bh->b_size = bsize;
BUG();
bh->b_end_io = end_sync_read;
bh->b_private = r1_bh;
+ bh->b_blocknr = sector_nr;
bh->b_rsector = sector_nr;
init_waitqueue_head(&bh->b_wait);
md_error (r1_bh->mddev, bh->b_dev);
if (atomic_dec_and_test(&r1_bh->remaining)) {
mddev_t *mddev = r1_bh->mddev;
- unsigned long sect = bh->b_blocknr * (bh->b_size>>9);
+ unsigned long sect = bh->b_blocknr;
int size = bh->b_size;
raid1_free_buf(r1_bh);
sync_request_done(sect, mddev_to_conf(mddev));
action[failed_num] = WRITE+1;
locked++;
set_bit(STRIPE_INSYNC, &sh->state);
- if (conf->disks[i].operational)
- md_sync_acct(conf->disks[i].dev, bh->b_size>>9);
+ if (conf->disks[failed_num].operational)
+ md_sync_acct(conf->disks[failed_num].dev, bh->b_size>>9);
else if (conf->spare)
md_sync_acct(conf->spare->dev, bh->b_size>>9);
struct video_picture picture;
int height;
int width;
+ struct semaphore lock;
};
struct i2c_info
return -EFAULT;
if(v<0 || v>3)
return -EINVAL;
+ down(&pd->lock);
pms_videosource(v&1);
pms_vcrinput(v>>1);
+ up(&pd->lock);
return 0;
}
case VIDIOCGTUNER:
return -EFAULT;
if(v.tuner)
return -EINVAL;
+ down(&pd->lock);
switch(v.mode)
{
case VIDEO_MODE_AUTO:
pms_format(2);
break;
default:
+ up(&pd->lock);
return -EINVAL;
}
+ up(&pd->lock);
return 0;
}
case VIDIOCGPICT:
* Now load the card.
*/
+ down(&pd->lock);
pms_brightness(p.brightness>>8);
pms_hue(p.hue>>8);
pms_colour(p.colour>>8);
pms_contrast(p.contrast>>8);
+ up(&pd->lock);
return 0;
}
case VIDIOCSWIN:
return -EINVAL;
pd->width=vw.width;
pd->height=vw.height;
+ down(&pd->lock);
pms_resolution(pd->width, pd->height);
- /* Ok we figured out what to use from our wide choice */
+ up(&pd->lock); /* Ok we figured out what to use from our wide choice */
return 0;
}
case VIDIOCGWIN:
struct pms_device *pd=(struct pms_device *)v;
int len;
- /* FIXME: semaphore this */
+ down(&pd->lock);
len=pms_capture(pd, buf, (pd->picture.depth==16)?0:1,count);
+ up(&pd->lock);
return len;
}
return -ENODEV;
}
memcpy(&pms_device, &pms_template, sizeof(pms_template));
+ init_MUTEX(&pms_device.lock);
pms_device.height=240;
pms_device.width=320;
pms_swsense(75);
if(vtune.tuner != 0);
return -EINVAL;
- strcpy(vtune.name, "Foo-tuner");
+ strcpy(vtune.name, "no tuner");
vtune.rangelow = 0;
vtune.rangehigh = 0;
vtune.flags = VIDEO_TUNER_NORM;
#if defined(__powerpc__)
// 89/9/1 modify,
// np->bcrvalue=0x04 | 0x0x38; /* big-endian, 256 burst length */
- np->bcrvalue = 0x04 | 0x0 x10; /* big-endian, tx 8 burst length */
- a np->cralue = 0xe00; /* rx 128 burst length */
+ np->bcrvalue = 0x04 | 0x10; /* big-endian, tx 8 burst length */
+ np->crvalue = 0xe00; /* rx 128 burst length */
#elif defined(__alpha__)
// 89/9/1 modify,
// np->bcrvalue=0x38; /* little-endian, 256 burst length */
np->bcrvalue = 0x10; /* little-endian, 8 burst length */
- np->cralue = 0xe00; /* rx 128 burst length */
+ np->crvalue = 0xe00; /* rx 128 burst length */
#elif defined(__i386__)
#if defined(MODULE)
// 89/9/1 modify,
- 2001-05-10 Fred Barnes <frmb2@ukc.ac.uk>
+2001-05-22 Juan Quintela <quintela@mandrakesoft.com>
+
+ * parport_amiga.c: Set printk levels.
+ * parport_gsc.c: Likewise.
+ * parport_mfc3.c: Likewise.
+ * parport_pc.c: Likewise.
+ * parport_sunbpp.c: Likewise.
+ * probe.c: Likewise.
+ * share.c: Likewise.
+
+2001-05-10 Fred Barnes <frmb2@ukc.ac.uk>
* parport_pc.c (parport_pc_epp_read_data): added support for
reading from a w91284pic peripheral, flag is PARPORT_W91284PIC.
static void amiga_write_data(struct parport *p, unsigned char data)
{
- DPRINTK("write_data %c\n",data);
+ DPRINTK(KERN_DEBUG "write_data %c\n",data);
/* Triggers also /STROBE. This behavior cannot be changed */
ciaa.prb = data;
mb();
static void amiga_write_control(struct parport *p, unsigned char control)
{
- DPRINTK("write_control %02x\n",control);
+ DPRINTK(KERN_DEBUG "write_control %02x\n",control);
/* No implementation possible */
}
static unsigned char amiga_read_control( struct parport *p)
{
- DPRINTK("read_control \n");
+ DPRINTK(KERN_DEBUG "read_control \n");
return control_amiga_to_pc(0);
}
{
unsigned char old;
- DPRINTK("frob_control mask %02x, value %02x\n",mask,val);
+ DPRINTK(KERN_DEBUG "frob_control mask %02x, value %02x\n",mask,val);
old = amiga_read_control(p);
amiga_write_control(p, (old & ~mask) ^ val);
return old;
unsigned char status;
status = status_amiga_to_pc(ciab.pra & 7);
- DPRINTK("read_status %02x\n", status);
+ DPRINTK(KERN_DEBUG "read_status %02x\n", status);
return status;
}
static void amiga_data_forward(struct parport *p)
{
- DPRINTK("forward\n");
+ DPRINTK(KERN_DEBUG "forward\n");
ciaa.ddrb = 0xff; /* all pins output */
mb();
}
static void amiga_data_reverse(struct parport *p)
{
- DPRINTK("reverse\n");
+ DPRINTK(KERN_DEBUG "reverse\n");
ciaa.ddrb = 0; /* all pins input */
mb();
}
irq = busdevice_alloc_irq(d);
if (!irq) {
- printk("IRQ not found for parallel device at 0x%p\n", d->hpa);
+ printk(KERN_DEBUG "IRQ not found for parallel device at 0x%p\n", d->hpa);
return -ENODEV;
}
*/
if (!pdc_add_valid( (void *)(port+4))) {
/* Initialize bidirectional-mode (0x10) & data-tranfer-mode #1 (0x20) */
- printk("%s: initialize bidirectional-mode.\n", __FUNCTION__);
+ printk(KERN_DEBUG "%s: initialize bidirectional-mode.\n", __FUNCTION__);
parport_writeb ( (0x10 + 0x20), port + 4);
} else {
- printk("%s: enhanced parport-modes not supported.\n", __FUNCTION__);
+ printk(KERN_DEBUG "%s: enhanced parport-modes not supported.\n", __FUNCTION__);
}
if (parport_gsc_probe_port(port, 0,
static void mfc3_write_data(struct parport *p, unsigned char data)
{
-DPRINTK("write_data %c\n",data);
+DPRINTK(KERN_DEBUG "write_data %c\n",data);
dummy = pia(p)->pprb; /* clears irq bit */
/* Triggers also /STROBE.*/
static void mfc3_write_control(struct parport *p, unsigned char control)
{
-DPRINTK("write_control %02x\n",control);
+DPRINTK(KERN_DEBUG "write_control %02x\n",control);
pia(p)->ppra = (pia(p)->ppra & 0x1f) | control_pc_to_mfc3(control);
}
static unsigned char mfc3_read_control( struct parport *p)
{
-DPRINTK("read_control \n");
+DPRINTK(KERN_DEBUG "read_control \n");
return control_mfc3_to_pc(pia(p)->ppra & 0xe0);
}
{
unsigned char old;
-DPRINTK("frob_control mask %02x, value %02x\n",mask,val);
+DPRINTK(KERN_DEBUG "frob_control mask %02x, value %02x\n",mask,val);
old = mfc3_read_control(p);
mfc3_write_control(p, (old & ~mask) ^ val);
return old;
#if 0 /* currently unused */
static void mfc3_write_status( struct parport *p, unsigned char status)
{
-DPRINTK("write_status %02x\n",status);
+DPRINTK(KERN_DEBUG "write_status %02x\n",status);
pia(p)->ppra = (pia(p)->ppra & 0xe0) | status_pc_to_mfc3(status);
}
#endif
unsigned char status;
status = status_mfc3_to_pc(pia(p)->ppra & 0x1f);
-DPRINTK("read_status %02x\n", status);
+DPRINTK(KERN_DEBUG "read_status %02x\n", status);
return status;
}
static void mfc3_data_forward(struct parport *p)
{
- DPRINTK("forward\n");
+ DPRINTK(KERN_DEBUG "forward\n");
pia(p)->crb &= ~PIA_DDR; /* make data direction register visible */
pia(p)->pddrb = 255; /* all pins output */
pia(p)->crb |= PIA_DDR; /* make data register visible - default */
static void mfc3_data_reverse(struct parport *p)
{
- DPRINTK("reverse\n");
+ DPRINTK(KERN_DEBUG "reverse\n");
pia(p)->crb &= ~PIA_DDR; /* make data direction register visible */
pia(p)->pddrb = 0; /* all pins input */
pia(p)->crb |= PIA_DDR; /* make data register visible - default */
unsigned char oecr;
int mode;
- DPRINTK("parport change_mode ECP-ISA to mode 0x%02x\n",m);
+ DPRINTK(KERN_INFO "parport change_mode ECP-ISA to mode 0x%02x\n",m);
if (!priv->ecr) {
printk (KERN_DEBUG "change_mode: but there's no ECR!\n");
cr27=inb(io+1);
outb(0xaa,io);
- printk ("SMSC 37c669 LPT Config: cr_1=0x%02x, 4=0x%02x, "
+ printk (KERN_INFO "SMSC 37c669 LPT Config: cr_1=0x%02x, 4=0x%02x, "
"A=0x%2x, 23=0x%02x, 26=0x%02x, 27=0x%02x\n",
cr1,cr4,cra,cr23,cr26,cr27);
/* The documentation calls DMA and IRQ-Lines by letters, so
the board maker can/will wire them
appropriately/randomly... G=reserved H=IDE-irq, */
- printk ("SMSC LPT Config: io=0x%04x, irq=%c, dma=%c, "
+ printk (KERN_INFO "SMSC LPT Config: io=0x%04x, irq=%c, dma=%c, "
"fifo threshold=%d\n", cr23*4,
(cr27 &0x0f) ? 'A'-1+(cr27 &0x0f): '-',
(cr26 &0x0f) ? 'A'-1+(cr26 &0x0f): '-', cra & 0x0f);
- printk("SMSC LPT Config: enabled=%s power=%s\n",
+ printk(KERN_INFO "SMSC LPT Config: enabled=%s power=%s\n",
(cr23*4 >=0x100) ?"yes":"no", (cr1 & 4) ? "yes" : "no");
- printk("SMSC LPT Config: Port mode=%s, EPP version =%s\n",
+ printk(KERN_INFO "SMSC LPT Config: Port mode=%s, EPP version =%s\n",
(cr1 & 0x08 ) ? "Standard mode only (SPP)" : modes[cr4 & 0x03],
(cr4 & 0x40) ? "1.7" : "1.9");
while((superios[i].io!= 0) && (i<NR_SUPERIOS))
i++;
if(i==NR_SUPERIOS)
- printk("Super-IO: too many chips!\n");
+ printk(KERN_INFO "Super-IO: too many chips!\n");
else {
int d;
switch (cr23*4) {
crf0=inb(io+1);
outb(0xaa,io);
- printk("Winbond LPT Config: cr_30=%02x 60,61=%02x%02x "
+ printk(KERN_INFO "Winbond LPT Config: cr_30=%02x 60,61=%02x%02x "
"70=%02x 74=%02x, f0=%02x\n", cr30,cr60,cr61,cr70,cr74,crf0);
- printk("Winbond LPT Config: active=%s, io=0x%02x%02x irq=%d, ",
+ printk(KERN_INFO "Winbond LPT Config: active=%s, io=0x%02x%02x irq=%d, ",
(cr30 & 0x01) ? "yes":"no", cr60,cr61,cr70&0x0f );
if ((cr74 & 0x07) > 3)
printk("dma=none\n");
else
printk("dma=%d\n",cr74 & 0x07);
- printk("Winbond LPT Config: irqtype=%s, ECP fifo threshold=%d\n",
+ printk(KERN_INFO "Winbond LPT Config: irqtype=%s, ECP fifo threshold=%d\n",
irqtypes[crf0>>7], (crf0>>3)&0x0f);
- printk("Winbond LPT Config: Port mode=%s\n", modes[crf0 & 0x07]);
+ printk(KERN_INFO "Winbond LPT Config: Port mode=%s\n", modes[crf0 & 0x07]);
if(cr30 & 0x01) { /* the settings can be interrogated later ... */
while((superios[i].io!= 0) && (i<NR_SUPERIOS))
i++;
if(i==NR_SUPERIOS)
- printk("Super-IO: too many chips!\n");
+ printk(KERN_INFO "Super-IO: too many chips!\n");
else {
superios[i].io = (cr60<<8)|cr61;
superios[i].irq = cr70&0x0f;
non-winbond register */
return;
- printk("Winbond chip at EFER=0x%x key=0x%02x devid=%02x devrev=%02x "
+ printk(KERN_INFO "Winbond chip at EFER=0x%x key=0x%02x devid=%02x devrev=%02x "
"oldid=%02x\n", efer,key,devid,devrev,oldid);
id=(devid<<8) | devrev;
else progif=0;
if(type==NULL)
- printk("Winbond unknown chip type\n");
+ printk(KERN_INFO "Winbond unknown chip type\n");
else
- printk("Winbond chip type %s\n",type);
+ printk(KERN_INFO "Winbond chip type %s\n",type);
if(progif==2)
show_parconfig_winbond(efer,key);
return;
func=NULL;
- printk("SMSC chip at EFER=0x%x key=0x%02x devid=%02x devrev=%02x\n",
+ printk(KERN_INFO "SMSC chip at EFER=0x%x key=0x%02x devid=%02x devrev=%02x\n",
efer,key,devid,devrev);
id=(devid<<8) | devrev;
else if (devid==0x66) type="37c666GT";
if(type==NULL)
- printk("SMSC unknown chip type\n");
+ printk(KERN_INFO "SMSC unknown chip type\n");
else
- printk("SMSC chip type %s\n",type);
+ printk(KERN_INFO "SMSC chip type %s\n",type);
if(func) (func)(efer,key);
return;
static void __devinit detect_and_report_winbond (void)
{
- printk("Winbond Super-IO detection, now testing ports 3F0,370,250,4E,2E ...\n");
+ printk(KERN_DEBUG "Winbond Super-IO detection, now testing ports 3F0,370,250,4E,2E ...\n");
winbond_check(0x3f0,0x87);
winbond_check(0x370,0x87);
static void __devinit detect_and_report_smsc (void)
{
- printk("SMSC Super-IO detection, now testing Ports 2F0, 370 ...\n");
+ printk(KERN_DEBUG "SMSC Super-IO detection, now testing Ports 2F0, 370 ...\n");
smsc_check(0x3f0,0x55);
smsc_check(0x370,0x55);
smsc_check(0x3f0,0x44);
printk("%d",intrline[(configb >>3) & 0x07]);
else
printk("<none or set by other means>");
- printk ( " dma=");
+ printk (" dma=");
if( (configb & 0x03 ) == 0x00)
printk("<none or set by other means>\n");
else
struct bpp_regs *regs = (struct bpp_regs *)p->base;
sbus_writeb(d, ®s->p_dr);
- dprintk(("wrote 0x%x\n", d));
+ dprintk((KERN_DEBUG "wrote 0x%x\n", d));
}
static unsigned char parport_sunbpp_read_data(struct parport *p)
if (!(value_tcr & P_TCR_BUSY))
bits |= PARPORT_STATUS_BUSY;
- dprintk(("tcr 0x%x ir 0x%x\n", regs->p_tcr, regs->p_ir));
- dprintk(("read status 0x%x\n", bits));
+ dprintk((KERN_DEBUG "tcr 0x%x ir 0x%x\n", regs->p_tcr, regs->p_ir));
+ dprintk((KERN_DEBUG "read status 0x%x\n", bits));
return bits;
}
if (value_or & P_OR_SLCT_IN)
bits |= PARPORT_CONTROL_SELECT;
- dprintk(("tcr 0x%x or 0x%x\n", regs->p_tcr, regs->p_or));
- dprintk(("read control 0x%x\n", bits));
+ dprintk((KERN_DEBUG "tcr 0x%x or 0x%x\n", regs->p_tcr, regs->p_or));
+ dprintk((KERN_DEBUG "read control 0x%x\n", bits));
return bits;
}
unsigned char value_tcr = sbus_readb(®s->p_tcr);
unsigned char value_or = sbus_readb(®s->p_or);
- dprintk(("frob1: tcr 0x%x or 0x%x\n", regs->p_tcr, regs->p_or));
+ dprintk((KERN_DEBUG "frob1: tcr 0x%x or 0x%x\n", regs->p_tcr, regs->p_or));
if (mask & PARPORT_CONTROL_STROBE) {
if (val & PARPORT_CONTROL_STROBE) {
value_tcr &= ~P_TCR_DS;
sbus_writeb(value_or, ®s->p_or);
sbus_writeb(value_tcr, ®s->p_tcr);
- dprintk(("frob2: tcr 0x%x or 0x%x\n", regs->p_tcr, regs->p_or));
+ dprintk((KERN_DEBUG "frob2: tcr 0x%x or 0x%x\n", regs->p_tcr, regs->p_or));
return parport_sunbpp_read_control(p);
}
struct bpp_regs *regs = (struct bpp_regs *)p->base;
unsigned char value_tcr = sbus_readb(®s->p_tcr);
- dprintk(("forward\n"));
+ dprintk((KERN_DEBUG "forward\n"));
value_tcr &= ~P_TCR_DIR;
sbus_writeb(value_tcr, ®s->p_tcr);
}
struct bpp_regs *regs = (struct bpp_regs *)p->base;
u8 val = sbus_readb(®s->p_tcr);
- dprintk(("reverse\n"));
+ dprintk((KERN_DEBUG "reverse\n"));
val |= P_TCR_DIR;
sbus_writeb(val, ®s->p_tcr);
}
struct bpp_regs *regs;
unsigned char value_tcr;
- dprintk(("init_one_port(%p): ranges, alloc_io, ", sdev));
+ dprintk((KERN_DEBUG "init_one_port(%p): ranges, alloc_io, ", sdev));
irq = sdev->irqs[0];
base = sbus_ioremap(&sdev->resource[0], 0,
sdev->reg_addrs[0].reg_size,
memcpy (ops, &parport_sunbpp_ops, sizeof (struct parport_operations));
- dprintk(("register_port, "));
+ dprintk(("register_port\n"));
if (!(p = parport_register_port(base, irq, dma, ops))) {
kfree(ops);
sbus_iounmap(base, size);
p->size = size;
- dprintk(("init_one_port: request_irq(%08x:%p:%x:%s:%p) ",
+ dprintk((KERN_DEBUG "init_one_port: request_irq(%08x:%p:%x:%s:%p) ",
p->irq, parport_sunbpp_interrupt, SA_SHIRQ, p->name, p));
if ((err = request_irq(p->irq, parport_sunbpp_interrupt,
SA_SHIRQ, p->name, p)) != 0) {
}
regs = (struct bpp_regs *)p->base;
- dprintk(("forward\n"));
+ dprintk((KERN_DEBUG "forward\n"));
value_tcr = sbus_readb(®s->p_tcr);
value_tcr &= ~P_TCR_DIR;
sbus_writeb(value_tcr, ®s->p_tcr);
struct parport_device_info *info = &port->probe_info[device + 1];
if (!txt) {
- printk("%s probe: memory squeeze\n", port->name);
+ printk(KERN_WARNING "%s probe: memory squeeze\n", port->name);
return;
}
strcpy(txt, str);
if (ep != str[i])
val[i] = r;
else {
- printk("parport: bad specifier `%s'\n", str[i]);
+ printk(KERN_ERR "parport: bad specifier `%s'\n", str[i]);
return -1;
}
}
*/
scsi_insert_special_req(SRpnt, 0);
- SCSI_LOG_MLQUEUE(3, printk("Leaving scsi_do_cmd()\n"));
+ SCSI_LOG_MLQUEUE(3, printk("Leaving scsi_do_req()\n"));
}
/*
SCpnt->abort_reason = 0;
SCpnt->result = 0;
- SCSI_LOG_MLQUEUE(3, printk("Leaving scsi_do_cmd()\n"));
+ SCSI_LOG_MLQUEUE(3, printk("Leaving scsi_init_cmd_from_req()\n"));
}
/*
* 20010228-dh patch from David Huggins - cs_update_ptr recursion.
* 20010409-tw add hercules game theatre XP amp code.
* 20010420-tw cleanup powerdown/up code.
+ * 20010521-tw eliminate pops, and fixes for powerdown.
*
* Status:
* Playback/Capture supported from 8k-48k.
};
#define CS46XX_MAJOR_VERSION "1"
-#define CS46XX_MINOR_VERSION "26"
+#define CS46XX_MINOR_VERSION "27"
#ifdef __ia64__
#define CS46XX_ARCH "64" //architecture key
{
struct ac97_codec *dev=card->ac97_codec[0];
+ CS_DBGOUT(CS_FUNCTION, 2, printk("cs46xx: cs_mute()+ %s\n",
+ (state == CS_TRUE) ? "Muting" : "UnMuting") );
+
if(state == CS_TRUE)
{
/*
cs_ac97_set(dev, (u8)BA0_AC97_MASTER_VOLUME_MONO, card->pm.u32AC97_master_volume_mono);
cs_ac97_set(dev, (u8)BA0_AC97_PCM_OUT_VOLUME, card->pm.u32AC97_pcm_out_volume);
}
+ CS_DBGOUT(CS_FUNCTION, 2, printk("cs46xx: cs_mute()-\n"));
}
/* set playback sample rate */
/*
* set to silence and let that clear the fifos.
*/
- memset(dmabuf->rawbuf, (dmabuf->fmt & CS_FMT_16BIT) ? 0 : 0x80,
- dmabuf->dmasize);
cs461x_clear_serial_FIFOs(card, CS_TYPE_DAC);
return -ERESTARTSYS;
}
"cs46xx: cs461x_powerdown()- 0 unable to powerdown. tmp=0x%x\n",tmp));
return 0;
}
+/*
+* for now, always keep power to the mixer block.
+* not sure why it's a problem but it seems to be if we power off.
+*/
+ type &= ~CS_POWER_MIXVON;
+ type &= ~CS_POWER_MIXVOFF;
cs_mute(card, CS_TRUE);
#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
static int (*midi_load_patch) (int devno, int format, const char *addr,
int offs, int count, int pmgr_flag) = NULL;
-#endif OSS_SUPPORT_SEQ
+#endif /* OSS_SUPPORT_SEQ */
/* if WF_DEBUG not defined, no run-time debugging messages will
be available via the debug flag setting. Given the current
int fx_mididev; /* devno for FX MIDI interface */
#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
int oss_dev; /* devno for OSS sequencer synth */
-#endif OSS_SUPPORT_SEQ
+#endif /* OSS_SUPPORT_SEQ */
char fw_version[2]; /* major = [0], minor = [1] */
char hw_version[2]; /* major = [0], minor = [1] */
bender: midi_synth_bender,
setup_voice: midi_synth_setup_voice
};
-#endif OSS_SUPPORT_SEQ
+#endif /* OSS_SUPPORT_SEQ */
#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_STATIC_INSTALL
(void) uninstall_wavefront ();
}
-#endif OSS_SUPPORT_STATIC_INSTALL
+#endif /* OSS_SUPPORT_STATIC_INSTALL */
/***********************************************************************/
/* WaveFront: Linux modular sound kernel installation interface */
&wavefront_oss_load_patch;
}
-#endif OSS_SUPPORT_SEQ
+#endif /* OSS_SUPPORT_SEQ */
/* Turn on Virtual MIDI, but first *always* turn it off,
since otherwise consectutive reloads of the driver will
} else {
synth_devs[dev.oss_dev] = &wavefront_operations;
}
-#endif OSS_SUPPORT_SEQ
+#endif /* OSS_SUPPORT_SEQ */
if (wavefront_init (1) < 0) {
printk (KERN_WARNING LOGNAME "initialization failed.\n");
#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
sound_unload_synthdev (dev.oss_dev);
-#endif OSS_SUPPORT_SEQ
+#endif /* OSS_SUPPORT_SEQ */
return -1;
}
#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
sound_unload_synthdev (dev.oss_dev);
-#endif OSS_SUPPORT_SEQ
+#endif /* OSS_SUPPORT_SEQ */
uninstall_wf_mpu ();
}
extern unsigned char coefficients3[404];
-#endif __ys225_h__
+#endif /* __ys225_h__ */
if (!camera->dev) {
minor_data [subminor] = NULL;
kfree (camera);
- }
- up (&camera->sem);
+ } else
+ up (&camera->sem);
+
up (&state_table_mutex);
dbg ("close #%d", subminor);
}
if (i >= MAX_CAMERAS) {
info ("Ignoring additional USB Camera");
- up (&state_table_mutex);
goto bye;
}
camera = minor_data [i] = kmalloc (sizeof *camera, GFP_KERNEL);
if (!camera) {
err ("no memory!");
- up (&state_table_mutex);
goto bye;
}
if (!camera->buf) {
minor_data [subminor] = NULL;
kfree (camera);
+ camera = NULL;
} else
camera->dev = NULL;
info ("USB Camera #%d disconnected", subminor);
usb_dec_dev_use (dev);
- up (&camera->sem);
+ if (camera != NULL)
+ up (&camera->sem);
up (&state_table_mutex);
}
* Version Information
*/
#define DRIVER_VERSION "v1.0.0"
-#define DRIVER_AUTHOR "Johannes Erdfelt, Randy Dunlap"
+#define DRIVER_AUTHOR "http://www.linux-usb.org/ibmcam/"
#define DRIVER_DESC "IBM/Xirlink C-it USB Camera Driver for Linux (c) 2000"
#define ENABLE_HEXDUMP 0 /* Enable if you need it */
#define PWC_H
#ifdef __KERNEL__
+#include <linux/module.h>
#include <asm/semaphore.h>
#include <asm/errno.h>
#include <linux/usb.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#else
#include <errno.h>
#include <sys/types.h>
{ USB_DEVICE(0x04b8, 0x0104) }, /* Perfection 1200U and 1200Photo*/
{ USB_DEVICE(0x04b8, 0x0106) }, /* Stylus Scan 2500 */
{ USB_DEVICE(0x04b8, 0x0107) }, /* Expression 1600 */
- { USB_DEVICE(0x04b8, 0x010b) }, /* Perfection 1240U */
{ USB_DEVICE(0x04b8, 0x010a) }, /* Perfection 1640SU and 1640SU Photo */
+ { USB_DEVICE(0x04b8, 0x010b) }, /* Perfection 1240U */
+ { USB_DEVICE(0x04b8, 0x010c) }, /* Perfection 640U */
/* Umax */
{ USB_DEVICE(0x1606, 0x0010) }, /* Astra 1220U */
{ USB_DEVICE(0x1606, 0x0030) }, /* Astra 2000U */
* See http://reality.sgi.com/bryder_wellington/ftdi_sio for upto date testing info
* and extra documentation
*
+ * (23/May/2001) Bill Ryder
+ * Added runtime debug patch (thanx Tyson D Sawyer).
+ * Cleaned up comments for 8U232
+ * Added parity, framing and overrun error handling
+ * Added receive break handling.
+ *
* (04/08/2001) gb
* Identify version on module load.
*
+ * (18/March/2001) Bill Ryder
+ * (Not released)
+ * Added send break handling. (requires kernel patch too)
+ * Fixed 8U232AM hardware RTS/CTS etc status reporting.
+ * Added flipbuf fix copied from generic device
+ *
* (12/3/2000) Bill Ryder
* Added support for 8U232AM device.
* Moved PID and VIDs into header file only.
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.0.0"
+#define DRIVER_VERSION "v1.1.0"
#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>"
#define DRIVER_DESC "USB FTDI RS232 Converters Driver"
{ } /* Terminating entry */
};
-/* THe 8U232AM has the same API as the sio - but it can support MUCH
- higher baudrates (921600 at 48MHz/230400 at 12MHz
- so .. it's baudrate setting codes are different */
+/* THe 8U232AM has the same API as the sio except for:
+ - it can support MUCH higher baudrates (921600 at 48MHz/230400
+ at 12MHz so .. it's baudrate setting codes are different
+ - it has a two byte status code.
+ - it returns characters very 16ms (the FTDI does it every 40ms)
+ */
static __devinitdata struct usb_device_id id_table_8U232AM [] = {
struct ftdi_private {
ftdi_type_t ftdi_type;
- char last_status_byte; /* device sends this every 40ms when open */
-
-
+ __u16 last_set_data_urb_value ; /* the last data state set - needed for doing a break */
};
/* function prototypes for a FTDI serial converter */
static int ftdi_sio_startup (struct usb_serial *serial);
static void ftdi_sio_read_bulk_callback (struct urb *urb);
static void ftdi_sio_set_termios (struct usb_serial_port *port, struct termios * old);
static int ftdi_sio_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
+static void ftdi_sio_break_ctl (struct usb_serial_port *port, int break_state );
/* Should rename most ftdi_sio's to ftdi_ now since there are two devices
which share common code */
write_bulk_callback: ftdi_sio_write_bulk_callback,
ioctl: ftdi_sio_ioctl,
set_termios: ftdi_sio_set_termios,
+ break_ctl: ftdi_sio_break_ctl,
startup: ftdi_sio_startup,
shutdown: ftdi_sio_shutdown,
};
write_bulk_callback: ftdi_sio_write_bulk_callback,
ioctl: ftdi_sio_ioctl,
set_termios: ftdi_sio_set_termios,
+ break_ctl: ftdi_sio_break_ctl,
startup: ftdi_8U232AM_startup,
shutdown: ftdi_sio_shutdown,
};
priv = serial->port->private = kmalloc(sizeof(struct ftdi_private), GFP_KERNEL);
if (!priv){
- err(__FUNCTION__"- kmalloc(%Zd) failed.", sizeof(struct ftdi_private));
+ err(__FUNCTION__"- kmalloc(%d) failed.", sizeof(struct ftdi_private));
return -ENOMEM;
}
priv = serial->port->private = kmalloc(sizeof(struct ftdi_private), GFP_KERNEL);
if (!priv){
- err(__FUNCTION__"- kmalloc(%Zd) failed.", sizeof(struct ftdi_private));
+ err(__FUNCTION__"- kmalloc(%d) failed.", sizeof(struct ftdi_private));
return -ENOMEM;
}
spin_unlock_irqrestore (&port->port_lock, flags);
- /* do not allow a task to be queued to deliver received data */
+ /* This will push the characters through immediately rather
+ than queue a task to deliver them */
port->tty->low_latency = 1;
/* No error checking for this (will get errors later anyway) */
unsigned char *first_byte = port->write_urb->transfer_buffer;
/* Was seeing a race here, got a read callback, then write callback before
- hitting interruptible_sleep_on - so wrapping in a wait_queue */
+ hitting interuptible_sleep_on - so wrapping in a wait_queue */
add_wait_queue(&port->write_wait, &wait);
set_current_state (TASK_INTERRUPTIBLE);
static void ftdi_sio_read_bulk_callback (struct urb *urb)
{ /* ftdi_sio_serial_buld_callback */
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
- struct ftdi_private *priv = (struct ftdi_private *)port->private;
struct usb_serial *serial;
struct tty_struct *tty = port->tty ;
+ char error_flag;
unsigned char *data = urb->transfer_buffer;
const int data_offset = 2;
if (urb->actual_length > 2) {
usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
} else {
- dbg("Just status");
+ dbg("Just status 0o%03o0o%03o",data[0],data[1]);
}
- priv->last_status_byte = data[0]; /* this has modem control lines */
/* TO DO -- check for hung up line and handle appropriately: */
/* send hangup */
/* See acm.c - you do a tty_hangup - eg tty_hangup(tty) */
/* if CD is dropped and the line is not CLOCAL then we should hangup */
-
+ /* Handle errors and break */
+ error_flag = TTY_NORMAL;
+ /* Although the device uses a bitmask and hence can have multiple */
+ /* errors on a packet - the order here sets the priority the */
+ /* error is returned to the tty layer */
+
+ if ( data[1] & FTDI_RS_OE ) {
+ error_flag = TTY_OVERRUN;
+ dbg("OVERRRUN error");
+ }
+ if ( data[1] & FTDI_RS_BI ) {
+ error_flag = TTY_BREAK;
+ dbg("BREAK received");
+ }
+ if ( data[1] & FTDI_RS_PE ) {
+ error_flag = TTY_PARITY;
+ dbg("PARITY error");
+ }
+ if ( data[1] & FTDI_RS_FE ) {
+ error_flag = TTY_FRAME;
+ dbg("FRAMING error");
+ }
if (urb->actual_length > data_offset) {
+
for (i = data_offset ; i < urb->actual_length ; ++i) {
- tty_insert_flip_char(tty, data[i], 0);
- }
+ /* have to make sure we don't overflow the buffer
+ with tty_insert_flip_char's */
+ if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
+ tty_flip_buffer_push(tty);
+ }
+ /* Note that the error flag is duplicated for
+ every character received since we don't know
+ which character it applied to */
+ tty_insert_flip_char(tty, data[i], error_flag);
+ }
tty_flip_buffer_push(tty);
+
+
+ }
+
+#ifdef NOT_CORRECT_BUT_KEEPING_IT_FOR_NOW
+ /* if a parity error is detected you get status packets forever
+ until a character is sent without a parity error.
+ This doesn't work well since the application receives a never
+ ending stream of bad data - even though new data hasn't been sent.
+ Therefore I (bill) have taken this out.
+ However - this might make sense for framing errors and so on
+ so I am leaving the code in for now.
+ */
+ else {
+ if (error_flag != TTY_NORMAL){
+ dbg("error_flag is not normal");
+ /* In this case it is just status - if that is an error send a bad character */
+ if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
+ tty_flip_buffer_push(tty);
+ }
+ tty_insert_flip_char(tty, 0xff, error_flag);
+ tty_flip_buffer_push(tty);
+ }
}
+#endif
/* Continue trying to always read */
FILL_BULK_URB(urb, serial->dev,
return(urb_value);
}
+static void ftdi_sio_break_ctl( struct usb_serial_port *port, int break_state )
+{
+ struct usb_serial *serial = port->serial;
+ struct ftdi_private *priv = (struct ftdi_private *)port->private;
+ __u16 urb_value = 0;
+ char buf[1];
+
+ /* break_state = -1 to turn on break, and 0 to turn off break */
+ /* see drivers/char/tty_io.c to see it used */
+ /* last_set_data_urb_value NEVER has the break bit set in it */
+
+ if (break_state) {
+ urb_value = priv->last_set_data_urb_value | FTDI_SIO_SET_BREAK;
+ } else {
+ urb_value = priv->last_set_data_urb_value;
+ }
+
+
+ if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ FTDI_SIO_SET_DATA_REQUEST,
+ FTDI_SIO_SET_DATA_REQUEST_TYPE,
+ urb_value , 0,
+ buf, 0, WDR_TIMEOUT) < 0) {
+ err(__FUNCTION__ " FAILED to enable/disable break state (state was %d)",break_state);
+ }
+
+ dbg(__FUNCTION__ " break state is %d - urb is %d",break_state, urb_value);
+
+}
+
+
+
/* As I understand this - old_termios contains the original termios settings */
/* and tty->termios contains the new setting to be used */
/* */
err("CSIZE was set but not CS5-CS8");
}
}
+
+ /* This is needed by the break command since it uses the same command - but is
+ * or'ed with this value */
+ priv->last_set_data_urb_value = urb_value;
+
if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
FTDI_SIO_SET_DATA_REQUEST,
FTDI_SIO_SET_DATA_REQUEST_TYPE,
struct usb_serial *serial = port->serial;
struct ftdi_private *priv = (struct ftdi_private *)port->private;
__u16 urb_value=0; /* Will hold the new flags */
- char buf[1];
+ char buf[2];
int ret, mask;
dbg(__FUNCTION__ " cmd 0x%04x", cmd);
case TIOCMGET:
dbg(__FUNCTION__ " TIOCMGET");
- /* The MODEM_STATUS_REQUEST works for the sio but not the 232 */
if (priv->ftdi_type == sio){
- /* TO DECIDE - use the 40ms status packets or not? */
- /* PRO: No need to send urb */
- /* CON: Could be 40ms out of date */
-
/* Request the status from the device */
if ((ret = usb_control_msg(serial->dev,
usb_rcvctrlpipe(serial->dev, 0),
return(ret);
}
} else {
- /* This gets updated every 40ms - so just copy it in */
- buf[0] = priv->last_status_byte;
+ /* the 8U232AM returns a two byte value (the sio is a 1 byte value) - in the same
+ format as the data returned from the in point */
+ if ((ret = usb_control_msg(serial->dev,
+ usb_rcvctrlpipe(serial->dev, 0),
+ FTDI_SIO_GET_MODEM_STATUS_REQUEST,
+ FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
+ 0, 0,
+ buf, 2, WDR_TIMEOUT)) < 0 ) {
+ err(__FUNCTION__ " Could not get modem status of device - err: %d",
+ ret);
+ return(ret);
+ }
}
return put_user((buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) |
#define FTDI_SIO_SET_DATA_STOP_BITS_1 (0x0 << 11 )
#define FTDI_SIO_SET_DATA_STOP_BITS_15 (0x1 << 11 )
#define FTDI_SIO_SET_DATA_STOP_BITS_2 (0x2 << 11 )
-
+#define FTDI_SIO_SET_BREAK (0x1 << 14)
/* FTDI_SIO_SET_DATA */
/*
* 0 = 1
* 1 = 1.5
* 2 = 2
- * B14..15 Reserved
+ * B14
+ * 1 = TX ON (break)
+ * 0 = TX OFF (normal state)
+ * B15 Reserved
*
*/
* B6 Transmitter Empty (TEMT)
* B7 Error in RCVR FIFO
*
+ */
+#define FTDI_RS_DR 1
+#define FTDI_RS_OE (1<<1)
+#define FTDI_RS_PE (1<<2)
+#define FTDI_RS_FE (1<<3)
+#define FTDI_RS_BI (1<<4)
+#define FTDI_RS_THRE (1<<5)
+#define FTDI_RS_TEMT (1<<6)
+#define FTDI_RS_FIFO (1<<7)
+
+/*
* OUT Endpoint
*
* This device reserves the first bytes of data on this endpoint contain the length
* Basic tests have been performed with minicom/zmodem transfers and
* modem dialing under Linux 2.4.0-test10 (for me it works fine).
*
+ * 04-May-2001 Stelian Pop
+ * - Set the maximum bulk output size for Sitecom U232-P25 model to 16 bytes
+ * instead of the device reported 32 (using 32 bytes causes many data
+ * loss, Windows driver uses 16 too).
+ *
+ * 02-May-2001 Stelian Pop
+ * - Fixed the baud calculation for Sitecom U232-P25 model
+ *
* 08-Apr-2001 gb
* - Identify version on module load.
*
urb_priv->length = size;
urb_priv->ed = ed;
- /* allocate the TDs */
+ /* allocate the TDs (updating hash chains) */
+ spin_lock_irqsave (&usb_ed_lock, flags);
for (i = 0; i < size; i++) {
- urb_priv->td[i] = td_alloc (ohci, mem_flags);
+ urb_priv->td[i] = td_alloc (ohci, SLAB_ATOMIC);
if (!urb_priv->td[i]) {
urb_priv->length = i;
urb_free_priv (ohci, urb_priv);
+ spin_unlock_irqrestore (&usb_ed_lock, flags);
usb_dec_dev_use (urb->dev);
return -ENOMEM;
}
if (ed->state == ED_NEW || (ed->state & ED_DEL)) {
urb_free_priv (ohci, urb_priv);
+ spin_unlock_irqrestore (&usb_ed_lock, flags);
usb_dec_dev_use (urb->dev);
return -EINVAL;
}
}
if (bustime < 0) {
urb_free_priv (ohci, urb_priv);
+ spin_unlock_irqrestore (&usb_ed_lock, flags);
usb_dec_dev_use (urb->dev);
return bustime;
}
#endif
}
- spin_lock_irqsave (&usb_ed_lock, flags);
urb->actual_length = 0;
urb->hcpriv = urb_priv;
urb->status = USB_ST_URB_PENDING;
if (ed->state == ED_NEW) {
ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP); /* skip ed */
/* dummy td; end of td list for ed */
- td = td_alloc (ohci, mem_flags);
+ td = td_alloc (ohci, SLAB_ATOMIC);
/* hash the ed for later reverse mapping */
if (!td || !hash_add_ed (ohci, (ed_t *)ed)) {
/* out of memory */
// Count and limit the retries though; either hardware or
// software errors can go forever...
#endif
+ hc_reset (ohci);
}
if (ints & OHCI_INTR_WDH) {
writel (OHCI_INTR_SO, ®s->intrenable);
}
+ // FIXME: this assumes SOF (1/ms) interrupts don't get lost...
if (ints & OHCI_INTR_SF) {
unsigned int frame = le16_to_cpu (ohci->hcca->frame_no) & 1;
writel (OHCI_INTR_SF, ®s->intrdisable);
if (pci_enable_device(dev) < 0)
return -ENODEV;
+
+ if (!dev->irq) {
+ err("found OHCI device with no IRQ assigned. check BIOS settings!");
+ return -ENODEV;
+ }
/* we read its hardware registers as memory */
mem_resource = pci_resource_start(dev, 0);
+++ /dev/null
-/*
- (C) 2001 Nemosoft Unv. nemosoft@smcc.demon.nl
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-*/
-
-
-/* 'Viewport' conversion routines. These functions convert from one colour
- space to another, taking into account that the source image has a smaller
- size than the view, and is placed inside the view:
-
- +-------view.x------------+
- | |
- | +---image.x---+ |
- | | | |
- | | | |
- | +-------------+ |
- | |
- +-------------------------+
-
- The image should always be smaller than the view. The offset (top-left
- corner of the image) should be precomputed, so you can place the image
- anywhere in the view.
-
- The functions take these parameters:
- - width image width (in pixels)
- - height image height (in pixels)
- - plus view width (in pixels)
- *src pointer at start of image
- *dst pointer at offset (!) in view
-*/
-
-
-#ifndef VCVT_H
-#define VCVT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Functions in vcvt_i386.S/vcvt_c.c */
-/* 4:2:0 YUV interlaced to RGB/BGR */
-void vcvt_420i_bgr24(int width, int height, int plus, void *src, void *dst);
-void vcvt_420i_rgb24(int width, int height, int plus, void *src, void *dst);
-void vcvt_420i_bgr32(int width, int height, int plus, void *src, void *dst);
-void vcvt_420i_rgb32(int width, int height, int plus, void *src, void *dst);
-
-
-/* Go from 420i to other yuv formats */
-void vcvt_420i_420p(int width, int height, int plus, void *src, void *dsty, void *dstu, void *dstv);
-void vcvt_420i_yuyv(int width, int height, int plus, void *src, void *dst);
-
-#if 0
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-/*
- Colour conversion routines (RGB <-> YUV) in plain C, with viewport
- extension.
- (C) 2001 Nemosoft Unv. nemosoft@smcc.demon.nl
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-
-/* Colour conversion routines that use a viewport. See the assembly code/.h
- files for more information.
-
- If you are always converting images where the image- and viewport size
- is the same, you can hack out the 'plus' variable and delete the
- offset calculation at the bottom of every for(line) {} loop. Otherwise,
- just call the functions with plus = width.
-
- NB: for these function, the YUV420 format is defined as:
- even lines: YYYY UU YYYY UU YYYY ..
- odd lines: YYYY VV YYYY VV YYYY ..
-*/
-
-#include "vcvt.h"
-
-
-#define PUSH_RGB24 1
-#define PUSH_BGR24 2
-#define PUSH_RGB32 3
-#define PUSH_BGR32 4
-
-/**
- \brief convert YUV 4:2:0 data into RGB, BGR, RGBa or BGRa
- \param width Width of yuv data, in pixels
- \param height Height of yuv data, in pixels
- \param plus Width of viewport, in pixels
- \param src beginning of YUV data
- \param dst beginning of RGB data, \b including the initial offset into the viewport
- \param push The requested RGB format
-
- \e push can be any of PUSH_RGB24, PUSH_BGR24, PUSH_RGB32 or PUSH_BGR32
-
- This is a really simplistic approach. Speedups are welcomed.
-*/
-static void vcvt_420i(int width, int height, int plus, unsigned char *src, unsigned char *dst, int push)
-{
- int line, col, linewidth;
- int y, u, v, yy, vr = 0, ug = 0, vg = 0, ub = 0;
- int r, g, b;
- unsigned char *sy, *su, *sv;
-
- linewidth = width + (width >> 1);
- sy = src;
- su = sy + 4;
- sv = su + linewidth;
-
- /* The biggest problem is the interlaced data, and the fact that odd
- add even lines have V and U data, resp.
- */
- for (line = 0; line < height; line++) {
- for (col = 0; col < width; col++) {
- y = *sy++;
- yy = y << 8;
- if ((col & 1) == 0) {
- /* only at even colums we update the u/v data */
- u = *su - 128;
- ug = 88 * u;
- ub = 454 * u;
- v = *sv - 128;
- vg = 183 * v;
- vr = 359 * v;
-
- su++;
- sv++;
- }
- if ((col & 3) == 3) {
- sy += 2; /* skip u/v */
- su += 4; /* skip y */
- sv += 4; /* skip y */
- }
-
- r = (yy + vr) >> 8;
- g = (yy - ug - vg) >> 8;
- b = (yy + ub ) >> 8;
- /* At moments like this, you crave for MMX instructions with saturation */
- if (r < 0) r = 0;
- if (r > 255) r = 255;
- if (g < 0) g = 0;
- if (g > 255) g = 255;
- if (b < 0) b = 0;
- if (b > 255) b = 255;
-
- switch(push) {
- case PUSH_RGB24:
- *dst++ = r;
- *dst++ = g;
- *dst++ = b;
- break;
-
- case PUSH_BGR24:
- *dst++ = b;
- *dst++ = g;
- *dst++ = r;
- break;
-
- case PUSH_RGB32:
- *dst++ = r;
- *dst++ = g;
- *dst++ = b;
- *dst++ = 0;
- break;
-
- case PUSH_BGR32:
- *dst++ = b;
- *dst++ = g;
- *dst++ = r;
- *dst++ = 0;
- break;
- }
- } /* ..for col */
- if (line & 1) { // odd line: go to next band
- su += linewidth;
- sv += linewidth;
- }
- else { // rewind u/v pointers
- su -= linewidth;
- sv -= linewidth;
- }
- /* Adjust destination pointer, using viewport. We have just
- filled one line worth of data, so only skip the difference
- between the view width and the image width.
- */
- if (push == PUSH_RGB24 || push == PUSH_BGR24)
- dst += ((plus - width) * 3);
- else
- dst += ((plus - width) * 4);
- } /* ..for line */
-}
-
-void vcvt_420i_rgb24(int width, int height, int plus, void *src, void *dst)
-{
- vcvt_420i(width, height, plus, (unsigned char *)src, (unsigned char *)dst, PUSH_RGB24);
-}
-
-void vcvt_420i_bgr24(int width, int height, int plus, void *src, void *dst)
-{
- vcvt_420i(width, height, plus, (unsigned char *)src, (unsigned char *)dst, PUSH_BGR24);
-}
-
-void vcvt_420i_rgb32(int width, int height, int plus, void *src, void *dst)
-{
- vcvt_420i(width, height, plus, (unsigned char *)src, (unsigned char *)dst, PUSH_RGB32);
-}
-
-void vcvt_420i_bgr32(int width, int height, int plus, void *src, void *dst)
-{
- vcvt_420i(width, height, plus, (unsigned char *)src, (unsigned char *)dst, PUSH_BGR32);
-}
-
-
-/** \brief Convert from interlaces YUV 420 to planar format
-*/
-void vcvt_420i_420p(int width, int height, int plus, void *src, void *dsty, void *dstu, void *dstv)
-{
- short *s, *dy, *du, *dv;
- int line, col;
-
- s = (short *)src;
- dy = (short *)dsty;
- du = (short *)dstu;
- dv = (short *)dstv;
- for (line = 0; line < height; line++) {
- for (col = 0; col < width; col += 4) {
- *dy++ = *s++;
- *dy++ = *s++;
- if (line & 1)
- *dv++ = *s++;
- else
- *du++ = *s++;
- } /* ..for col */
- dy += (plus - width);
- dv += ((plus - width) >> 1);
- du += ((plus - width) >> 1);
- } /* ..for line */
-}
-
-void vcvt_420i_yuyv(int width, int height, int plus, void *src, void *dst)
-{
- int line, col, linewidth;
- unsigned char *sy, *su, *sv, *d;
-
- linewidth = width + (width >> 1);
- sy = (unsigned char *)src;
- su = sy + 4;
- sv = su + linewidth;
- d = (unsigned char *)dst;
-
- for (line = 0; line < height; line++) {
- for (col = 0; col < width; col += 4) {
- /* four pixels in one go */
- *d++ = *sy++;
- *d++ = *su;
- *d++ = *sy++;
- *d++ = *sv;
-
- *d++ = *sy++;
- *d++ = *su++;
- *d++ = *sy++;
- *d++ = *sv++;
-
- sy += 2;
- su += 4;
- sv += 4;
- } /* ..for col */
- if (line & 1) { // odd line: go to next band
- su += linewidth;
- sv += linewidth;
- }
- else { // rewind u/v pointers
- su -= linewidth;
- sv -= linewidth;
- }
- /* Adjust for viewport width */
- d += ((plus - width) << 1);
- } /* ..for line */
-}
-
+++ /dev/null
-/*
- Colour conversion routines (RGB <-> YUV) in x86 assembly, with viewport
- extension.
- (C) 2001 Nemosoft Unv. nemosoft@smcc.demon.nl
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-
-/* The vcvt_* functions always start with width and height and plus, so these
- parameters are in 8(%ebp), 12(%ebp) and 16(%ebp).
- The other parameters can be 2 to 4 pointers, in one of these combinations:
- *src, *dst
- *srcy, *srcu, *srv, *dst
- *src, *dsty, *dstu, *dstv
- */
-
-#define __ASSEMBLY__
-#include <linux/linkage.h>
-
-.line 35
-
-#define Width 8(%ebp)
-#define Height 12(%ebp)
-#define Plus 16(%ebp)
-
-/* 2 parameters, 1 in, 1 out */
-#define Src2 20(%ebp)
-#define Dst2 24(%ebp)
-
-/* 4 parameters, 3 in, 1 out */
-#define SrcY 20(%ebp)
-#define SrcU 24(%ebp)
-#define SrcV 28(%ebp)
-#define Dst4 32(%ebp)
-
-/* 4 parameters, 1 in, 3 out */
-#define Src4 20(%ebp)
-#define DstY 24(%ebp)
-#define DstU 28(%ebp)
-#define DstV 32(%ebp)
-
-/* This buffer space used to be staticly allocted, but this is going to
- give problems with multiple cams (though I have yet to see it).
- Therefor, we reserve least 64 bytes (16 * 4) bytes on the stack,
- plus some space for extra variables.
- */
-
-#define PixelBuffer -64(%ebp)
-#define Uptr -68(%ebp)
-#define Vptr -72(%ebp)
-#define DstPlus -76(%ebp)
-
-#define StackSpace $76
-
- .text
-
-/* This function will load the src and destination pointers, including
- Uptr/Vptr when necessary, and test the width/height parameters.
- - %esi will be set to Src or SrcY
- - %edi will be set to Dst or DstY
- the carry flag will be set if any of these tests fail.
- It assumes %ebp has been set.
- */
-/* 2 parameters, src & dst */
-test_param_2:
- mov Src2, %esi
- mov Dst2, %edi
-
- cmp $0, %esi # NULL pointers?
- je param_fail
- cmp $0, %edi
- je param_fail
-
- jmp test_width_height
-
-/* 3 inputs, 1 output */
-test_param_31:
- mov Dst4, %edi # NULL pointers
- cmp $0, %edi
- je param_fail
-
- mov SrcV, %esi
- cmp $0, %esi
- je param_fail
- mov %esi, Vptr
-
- mov SrcU, %esi
- cmp $0, %esi
- je param_fail
- mov %esi, Uptr
-
- mov SrcY, %esi
- cmp $0, %esi
- je param_fail
-
- jmp test_width_height
-
-/* 1 input, 3 output */
-test_param_13:
- mov Src4, %esi # NULL pointers
- cmp $0, %esi
- je param_fail
-
- mov DstV, %edi
- cmp $0, %edi
- je param_fail
- mov %edi, Vptr
-
- mov DstU, %edi
- cmp $0, %edi
- je param_fail
- mov %edi, Uptr
-
- mov DstY, %edi
- cmp $0, %edi
- je param_fail
-
- jmp test_width_height
-
- nop
-
-test_width_height:
- cmpl $0, Width
- jbe param_fail
- testl $3, Width # multiple of 4?
- jnz param_fail # Nope...
-
- cmp $0, Height # check illegal height
- jbe param_fail
- testl $1, Height # Odd no. of lines?
- jnz param_fail # Aye
-
- /* fall through */
-
-/* exit points */
-param_ok:
- clc # Success: clear carry
- ret
-
-param_fail:
- stc # Fail: set carry
- ret
-
-
-
-# This will fill PixelBuffer with 4 grey scale pixels (Y)
-# In: %eax = Value (Y3Y2Y1Y0)
-# Out:
-# Modifies: %ecx (-4)
-# Destroys: %edx
-expand_4_y:
- mov %eax, %edx # Keep in edx (we need eax)
- lea PixelBuffer, %edi
-
-0: # This code is executed 4 times
- movzbl %dl, %eax # move, zero extending byte-to-long
- shl $8, %eax # 8 digit precision
-
- stosl # Expand into PixelBuffer
- stosl
- stosl
- add $4, %edi # Skip alpha
-
- shr $8, %edx # next Y
-
- dec %ecx
- test $3, %ecx
- jnz 0b
-
- ret # from expand_4_y
-
-# This will add the color factors to the (grey) values in PixelBuffer
-# In: %ebx (U1U0V1V0)
-# Out:
-# Modifies:
-# Destroys: %edi, %ebx, %eax, %edx
-expand_4_uv:
- lea PixelBuffer, %edi # reset pointer
-
- # V0
- sub $128, %bl
- movsbl %bl, %eax
- mov $359, %edx # Vr
- mul %edx
- add %eax, 0x00(%edi)
- add %eax, 0x10(%edi)
-
- movsbl %bl, %eax
- mov $183, %edx # Vg
- mul %edx
- sub %eax, 0x04(%edi)
- sub %eax, 0x14(%edi)
-
- # V1
- sub $128, %bh
- movsbl %bh, %eax
- mov $359, %edx # Vr
- mul %edx
- add %eax, 0x20(%edi)
- add %eax, 0x30(%edi)
-
- movsbl %bh, %eax
- mov $183, %edx # Vg
- mul %edx
- sub %eax, 0x24(%edi)
- sub %eax, 0x34(%edi)
-
- # U0
- bswap %ebx # Get U values in lower half
- sub $128, %bh
- movsbl %bh, %eax
- mov $88, %edx # Ug
- mul %edx
- sub %eax, 0x04(%edi)
- sub %eax, 0x14(%edi)
-
- movsbl %bh, %eax
- mov $454, %edx # Ub
- mul %edx
- add %eax, 0x08(%edi)
- add %eax, 0x18(%edi)
-
- # U1
- sub $128, %bl
- movsbl %bl, %eax
- mov $88, %edx # Ug
- mul %edx
- sub %eax, 0x24(%edi)
- sub %eax, 0x34(%edi)
-
- movsbl %bl, %eax
- mov $454, %edx # Ub
- mul %edx
- add %eax, 0x28(%edi)
- add %eax, 0x38(%edi)
- ret # expand_4_uv
-
-
-/* This function expands 4 420i pixels into PixelBuffer */
-do_four_yuvi:
- push %edi
-
- lodsl # 4 bytes at a time
-
- call expand_4_y
-
- # now do UV values. on even lines, Y is followed by U values; on
- # odd lines V values follow. The U and V values are always pushed
- # on the stack in this order:
- # U V
-
- # First, calculate offset per line (1.5 * width)
- mov Width, %ebx # width
- shl %ebx # 2 *
- add Width, %ebx # 3 *
- shr %ebx # 1.5 *
-
- # even or odd lines
- testl $1, Height
- jz 2f
-
- # odd line; we are at V data, but do U data first
- neg %ebx # make ebx offset negative
- mov (%esi,%ebx),%ax # U
- push %ax
- lodsw # V
- push %ax
- jmp 3f
-
-2: # even line
- lodsw # U
- push %ax
- sub $2, %ebx
- mov (%esi,%ebx), %ax # V
- push %ax
-
-3: # Okay, so we now have the U and V values... expand into PixelBuffer
-
- pop %ebx
- call expand_4_uv
-
- pop %edi
- ret # from do_four_yuvi
-
-
-# Do four pixels, in planar format
-do_four_yuvp:
- push %edi
-
- # The first part is the same as for interlaced (4 bytes Y)
- lodsl # 4 bytes at a time
- call expand_4_y
-
- # now gather U and V values...
- mov Uptr, %ebx # Use Uptr/Vptr
- mov (%ebx), %ax
- push %ax
- add $2, %ebx
- mov %ebx, Uptr
-
- mov Vptr, %ebx
- mov (%ebx), %ax
- push %ax
- add $2, %ebx
- mov %ebx, Vptr
-
- pop %ebx
- call expand_4_uv
-
- pop %edi
- ret
-
-
-# Do four pixels, in yuyv interlaced format
-do_four_yuyv:
- push %edi
-
- lodsl # v0y1u0y0
- mov %eax, %ebx
- bswap %ebx # y0u0y1v0
- mov %bh, %ah # v0y1y1y0
- and $0x00ff00ff, %ebx # __u0__v0
- push %ax # y1y0
-
- lodsl # v1y3u1y2 # mix register instructions
- mov %eax, %edx # so CPU pipeline doesnt stall
- rol $16, %eax # u1y2v1y3
- mov %dl, %dh # v1y3y2y2
- and $0xff00ff00, %eax # u1__v1__
- mov $0, %dl # v1y3y2__
- or %eax, %ebx # u1u0v1v0
- shl $8, %edx # y3y2____
- pop %dx # y3y2y1y0
- mov %edx, %eax
- call expand_4_y
- call expand_4_uv
-
- pop %edi
- ret
-
-limit_pixels:
- # Limit all values in PixelBuffer
- push %esi
- push %edi
- push %ecx
- lea PixelBuffer, %esi
- mov %esi, %edi
- mov $16, %ecx
-0: lodsl
- cmp $0, %eax # this would have been a perfect spot for CMOVxx instructions...
- jl 2f # except they only work on Pentium Pro processors,
- cmp $0xff00, %eax # and not even all of them
- jg 3f
- add $4, %edi # no use for stosl here
- loop 0b
- jmp 9f
-2: mov $0, %eax
- stosl
- loop 0b
- jmp 9f
-3: mov $0xff00, %eax
- stosl
- loop 0b
- jmp 9f
-
-9: pop %ecx
- pop %edi
- pop %esi
- ret # from limit_pixels
-
-/* Copy RGB values from PixelBuffer into destination buffer, 4 bytes
- with alpha
- */
-
-/* Push 3 pixel (12 bytes), in correct order */
-push_rgb24:
- push %ecx
- push %esi
- lea PixelBuffer, %esi
- mov $4, %ecx
-0: lodsl
- shr $8, %eax
- mov %al, (%edi) # Red
- lodsl
- shr $8, %eax
- mov %al, 1(%edi) # Green
- lodsl
- shr $8, %eax
- mov %al, 2(%edi) # Blue
- add $3, %edi
- lodsl # dummy
- loop 0b
- pop %esi
- pop %ecx
- ret
-
-/* Push 3 pixels (12 bytes), in wrong order */
-push_bgr24:
- push %ecx
- push %esi
- lea PixelBuffer, %esi
- mov $4, %ecx
-0: lodsl
- shr $8, %eax
- mov %al, 2(%edi) # Red
- lodsl
- shr $8, %eax
- mov %al, 1(%edi) # Green
- lodsl
- shr $8, %eax
- mov %al, (%edi) # Blue
- add $3, %edi
- lodsl # dummy
- loop 0b
- pop %esi
- pop %ecx
- ret
-
-/* The simplest format: push 4 bytes, RGBa */
-push_rgb32:
- push %ecx
- push %esi
- mov $16, %ecx
- lea PixelBuffer, %esi
-0: lodsl # red
- shr $8, %eax # 8 bit precision
- stosb
- loop 0b
- pop %esi
- pop %ecx
- ret
-
-
-/* Gosh. Would you believe it. They even made this format... (Qt 2.*) */
-push_bgr32:
- # copy all 4 values to output buffer
- push %ecx
- push %esi
- mov $4, %ecx
- lea PixelBuffer, %esi
-0: lodsl # red
- shr $8, %eax # 8 bit precision
- mov %al, 2(%edi)
- lodsl # green
- shr $8, %eax
- mov %al, 1(%edi)
- lodsl # blue
- shr $8, %eax
- mov %al, (%edi)
- add $4, %edi
- lodsl # dummy
- loop 0b
- pop %esi
- pop %ecx
- ret
-
-/*************************************/
-
-/* Functions to go from YUV interlaced formats to RGB */
-
-/* Go from interlaced to RGB, red first */
-
-ENTRY(vcvt_420i_rgb24)
- enter StackSpace, $0 # no extra space, no stackframes
- push %ebx
- push %esi
- push %edi
-
- call test_param_2
- jc 9f
-
- mov Plus, %eax # 3 bytes per pixel
- shl $1, %eax
- add Plus, %eax
- mov %eax, DstPlus
-
-0: mov Width, %ecx # width
- push %edi # Save dst pointer
-1: call do_four_yuvi
- call limit_pixels
- call push_rgb24
-
- cmp $0, %ecx
- jnz 1b # end of line?
- pop %edi # Get dst pointer
- add DstPlus, %edi # Add offset
- decl Height # yes; decrement line counter
- jnz 0b
-
-9: pop %edi
- pop %esi
- pop %ebx
- leave
- ret
-
-/* Go from interlaced to BGR, blue first */
-
-ENTRY(vcvt_420i_bgr24)
- enter StackSpace, $0 # no extra space, no stackframes
- push %ebx
- push %esi
- push %edi
-
- call test_param_2
- jc 9f
-
- mov Plus, %eax # 3 bytes per pixel
- shl $1, %eax
- add Plus, %eax
- mov %eax, DstPlus
-
-0: mov Width, %ecx # width
- push %edi
-1: call do_four_yuvi
- call limit_pixels
- call push_bgr24
-
- cmp $0, %ecx
- jnz 1b # end of line?
- pop %edi # Get dst pointer
- add DstPlus, %edi # Add offset
- decl Height # yes; decrement line counter
- jnz 0b
-
-9: pop %edi
- pop %esi
- pop %ebx
- leave
- ret
-
-
-/* From interlaced to RGBa */
-
-ENTRY(vcvt_420i_rgb32)
- enter StackSpace, $0 # no extra space, no stackframes
- push %ebx
- push %esi
- push %edi
-
- call test_param_2
- jc 9f
-
- mov Plus, %eax # 4 bytes per pixel
- shl $2, %eax
- mov %eax, DstPlus
-
-0: mov Width, %ecx # width
- push %edi
-1: call do_four_yuvi
- call limit_pixels
- call push_rgb32
-
- cmp $0, %ecx # end of line?
- jnz 1b
- pop %edi # Get dst pointer
- add DstPlus, %edi # Add offset
- decl Height # yes; decrement line counter
- jnz 0b
-
-9: pop %edi
- pop %esi
- pop %ebx
- leave
- ret
-
-/* Guess what? Go from interlaced to BGRa */
-
-ENTRY(vcvt_420i_bgr32)
- enter StackSpace, $0 # no extra space, no stackframes
- push %ebx
- push %esi
- push %edi
-
- call test_param_2
- jc 9f
-
- mov Plus, %eax # 4 bytes per pixel
- shl $2, %eax
- mov %eax, DstPlus
-
-0: mov Width, %ecx # width
- push %edi
-1: call do_four_yuvi
- call limit_pixels
- call push_bgr32
-
- cmp $0, %ecx # end of line?
- jnz 1b
- pop %edi # Get dst pointer
- add DstPlus, %edi # Add offset
- decl Height # yes; decrement line counter
- jnz 0b
-
-9: pop %edi
- pop %esi
- pop %ebx
- leave
- ret
-
-
-
-
-
-
-
-/**************************************************************************/
-
-
-/* Go from 'interlaced' (YYYY UU/VV) format to planar */
-
-ENTRY(vcvt_420i_420p)
- enter $80, $0 # 4 bytes extra space, no stackframes
- push %ebx # -4: width / 4
- push %esi
- push %edi
-
- call test_param_13
- jc 9f
-
- # Okay, this is fairly easy... we first grab the Y values (4 bytes
- # at a time), then rewind and do the U values, and repeat for V.
- # This leaves us with a nice planar format
-
- mov Width, %eax
- shr %eax
- shr %eax # width / 4
- mov %eax, -80(%ebp) # Store
-
- # Y
- mov Height, %edx # line counter
-0: mov -80(%ebp), %ecx
- push %edi
-1: lodsl # get 4 bytes...
- stosl # ...push 4 bytes
- add $2, %esi # Skip U or V
- loop 1b
- pop %edi
- add Plus, %edi
- dec %edx
- jnz 0b
-
- shrl $1, Plus # divide increment by 2
-
- # U
- mov Src4, %esi # rewind source pointer
- mov DstU, %edi
- add $4, %esi # set to U
- mov Height, %edx
- shr %edx # height / 2
- mov Width, %ebx
- shl %ebx
- add Width, %ebx
- shr %ebx # Width * 1.5 (line offset)
-
-2: mov -80(%ebp), %ecx # width / 4
- push %edi
-3: lodsw # 2 bytes at a time
- stosw
- add $4, %esi # skip Y
- loop 3b
- add %ebx, %esi # Skip line (U is on even lines)
- pop %edi
- add Plus, %edi
- dec %edx
- jnz 2b
-
- # V
- mov Src4, %esi # rewind, set to V in first odd line
- add $4, %esi
- add %ebx, %esi # register re-use; no compiler can beat that :)
- mov DstV, %edi # V ptr
- mov Height, %edx
- shr %edx # height / 2
-
-4: mov -80(%ebp), %ecx # Get width/4
- push %edi
-5: lodsw
- stosw
- add $4, %esi # Skip Y
- loop 5b
- add %ebx, %esi # Skip line (V is on odd lines)
- pop %edi
- add Plus, %edi
- dec %edx
- jnz 4b
-
- /* That's it! */
-
-9: pop %edi
- pop %esi
- pop %ebx
- leave
- ret
-
-
-/* Go from 4:2:0 interlaced to 'normal' YUYV */
-
-ENTRY(vcvt_420i_yuyv)
- enter $84, $0 # 8 bytes extra space, no stackframes
- push %ebx
- push %esi
- push %edi
-
- call test_param_2
- jc 9f
-
- mov Width, %ecx # -4: width / 4 = no. loops per line
- shr %ecx
- shr %ecx
- mov %ecx, -80(%ebp)
-
- mov Width, %ebx # -8: width * 1.5 = line offset
- shl %ebx
- add Width, %ebx
- shr %ebx
- mov %ebx, -84(%ebp)
-
- # Okay, this requires a bit of byte shuffling... we go from
- # YYYY UU
- # YYYY VV
- # to
- # YUYV YUYV
- # YUYV YUYV
- # which indeed takes up more space
-
- #
- shll Plus # Plus * 2
-0: mov -80(%ebp), %ecx
- push %edi
-1: lodsl # 4 Y in eax
- testl $1, Height # even or odd line?
- jnz 2f
-
- # Even
- mov -84(%ebp), %ebx
- mov (%ebx, %esi), %dx # 16 bits V
- shl $16, %edx # store in high word
- mov (%esi), %dx # 16 bits U
- add $2, %esi
- jmp 3f
-
-2: # Odd
- mov -84(%ebp), %ebx
- neg %ebx # negative offset
- mov (%esi), %dx # 16 bits V
- shl $16, %edx # store in high word
- mov (%ebx, %esi), %dx # 16 bits U
- add $2, %esi
-
-3: # eax = Y3Y2Y1Y0, edx = V1V0U1U0, ebx is free
- push %eax
-
- movzbl %al, %ebx # ______y0
- and $0xFF00, %eax # ____y1__
- shl $8, %eax # __y1____
- or %ebx, %eax # __y1__y0
- mov %edx, %ebx # v1v0u1u0
- shl $8, %ebx # v0u1u0__
- and $0xff00ff00, %ebx # v0__u0__
- or %ebx, %eax # v0y1u0y0
- stosl
-
- pop %eax # y3y2y1y0
- # Second half
- shr $8, %eax # __y3y2y1
- shr $8, %ax # __y3__y2
- and $0xff00ff00, %edx # v1__u1__
- or %edx, %eax # v1y3u1y2
- stosl
-
- loop 1b
- pop %edi
- add Plus, %edi
- decl Height # height--
- jnz 0b
- # Done
-
-9: pop %edi
- pop %esi
- pop %ebx
- leave
- ret
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/fs.h>
+#include <linux/blkdev.h>
#include <linux/msdos_fs.h>
#include <linux/fat_cvf.h>
struct buffer_head *default_fat_bread(struct super_block *sb, int block)
{
- return bread (sb->s_dev,block,512);
+ return bread (sb->s_dev, block, sb->s_blocksize);
}
+
struct buffer_head *default_fat_getblk(struct super_block *sb, int block)
{
- return getblk (sb->s_dev,block,512);
+ return getblk (sb->s_dev, block, sb->s_blocksize);
}
+
void default_fat_brelse(struct super_block *sb, struct buffer_head *bh)
{
brelse (bh);
}
+
void default_fat_mark_buffer_dirty (
struct super_block *sb,
struct buffer_head *bh)
{
mark_buffer_dirty (bh);
}
+
void default_fat_set_uptodate (
struct super_block *sb,
struct buffer_head *bh,
{
mark_buffer_uptodate(bh, val);
}
+
int default_fat_is_uptodate (struct super_block *sb, struct buffer_head *bh)
{
return buffer_uptodate(bh);
}
+
void default_fat_ll_rw_block (
struct super_block *sb,
int opr,
ll_rw_block(opr,nbreq,bh);
}
-struct buffer_head *bigblock_fat_bread (
- struct super_block *sb,
- int block)
-{
- struct buffer_head *ret = NULL;
- struct buffer_head *real;
- if (sb->s_blocksize == 1024){
- real = bread (sb->s_dev,block>>1,1024);
- } else {
- real = bread (sb->s_dev,block>>2,2048);
- }
+struct buffer_head *bigblock_fat_bread(struct super_block *sb, int block)
+{
+ unsigned int hardsect = get_hardsect_size(sb->s_dev);
+ int rblock, roffset;
+ struct buffer_head *real, *dummy;
+
+ if (hardsect <= sb->s_blocksize)
+ BUG();
+ dummy = NULL;
+ rblock = block / (hardsect / sb->s_blocksize);
+ roffset = (block % (hardsect / sb->s_blocksize)) * sb->s_blocksize;
+ real = bread(sb->s_dev, rblock, hardsect);
if (real != NULL) {
- ret = (struct buffer_head *)
- kmalloc (sizeof(struct buffer_head), GFP_KERNEL);
- if (ret != NULL) {
- /* #Specification: msdos / strategy / special device / dummy blocks
- * Many special device (Scsi optical disk for one) use
- * larger hardware sector size. This allows for higher
- * capacity.
-
- * Most of the time, the MS-DOS filesystem that sits
- * on this device is totally unaligned. It use logically
- * 512 bytes sector size, with logical sector starting
- * in the middle of a hardware block. The bad news is
- * that a hardware sector may hold data own by two
- * different files. This means that the hardware sector
- * must be read, patch and written almost all the time.
-
- * Needless to say that it kills write performance
- * on all OS.
-
- * Internally the linux msdos fs is using 512 bytes
- * logical sector. When accessing such a device, we
- * allocate dummy buffer cache blocks, that we stuff
- * with the information of a real one (1k large).
-
- * This strategy is used to hide this difference to
- * the core of the msdos fs. The slowdown is not
- * hidden though!
- */
- /*
- * The memset is there only to catch errors. The msdos
- * fs is only using b_data
- */
- memset (ret,0,sizeof(*ret));
- ret->b_data = real->b_data;
- if (sb->s_blocksize == 2048) {
- if (block & 3) ret->b_data += (block & 3) << 9;
- }else{
- if (block & 1) ret->b_data += 512;
- }
- ret->b_next = real;
- }else{
- brelse (real);
- }
+ dummy = kmalloc(sizeof(struct buffer_head), GFP_KERNEL);
+ if (dummy != NULL) {
+ memset(dummy, 0, sizeof(*dummy));
+ dummy->b_data = real->b_data + roffset;
+ dummy->b_next = real;
+ } else
+ brelse(real);
}
- return ret;
+
+ return dummy;
}
-void bigblock_fat_brelse (
- struct super_block *sb,
- struct buffer_head *bh)
+void bigblock_fat_brelse(struct super_block *sb, struct buffer_head *bh)
{
- brelse (bh->b_next);
- /*
- * We can free the dummy because a new one is allocated at
- * each fat_getblk() and fat_bread().
- */
- kfree (bh);
+ brelse(bh->b_next);
+ kfree(bh);
}
-void bigblock_fat_mark_buffer_dirty (
- struct super_block *sb,
- struct buffer_head *bh)
+void bigblock_fat_mark_buffer_dirty(struct super_block *sb, struct buffer_head *bh)
{
- mark_buffer_dirty (bh->b_next);
+ mark_buffer_dirty(bh->b_next);
}
-void bigblock_fat_set_uptodate (
- struct super_block *sb,
- struct buffer_head *bh,
- int val)
+void bigblock_fat_set_uptodate(struct super_block *sb, struct buffer_head *bh,
+ int val)
{
mark_buffer_uptodate(bh->b_next, val);
}
-int bigblock_fat_is_uptodate (
- struct super_block *sb,
- struct buffer_head *bh)
+int bigblock_fat_is_uptodate(struct super_block *sb, struct buffer_head *bh)
{
return buffer_uptodate(bh->b_next);
}
-void bigblock_fat_ll_rw_block (
- struct super_block *sb,
- int opr,
- int nbreq,
- struct buffer_head *bh[32])
+void bigblock_fat_ll_rw_block (struct super_block *sb, int opr, int nbreq,
+ struct buffer_head *bh[32])
{
struct buffer_head *tmp[32];
int i;
- for (i=0; i<nbreq; i++)
+
+ for (i = 0; i < nbreq; i++)
tmp[i] = bh[i]->b_next;
- ll_rw_block(opr,nbreq,tmp);
+ ll_rw_block(opr, nbreq, tmp);
}
int default_fat_access(struct super_block *sb,int nr,int new_value)
{
- struct buffer_head *bh,*bh2,*c_bh,*c_bh2;
- unsigned char *p_first,*p_last;
- int copy,first,last,next,b;
+ struct buffer_head *bh, *bh2, *c_bh, *c_bh2;
+ unsigned char *p_first, *p_last;
+ int copy, first, last, next, b;
if ((unsigned) (nr-2) >= MSDOS_SB(sb)->clusters)
return 0;
first = nr*3/2;
last = first+1;
}
- b = MSDOS_SB(sb)->fat_start + (first >> SECTOR_BITS);
+ b = MSDOS_SB(sb)->fat_start + (first >> sb->s_blocksize_bits);
if (!(bh = fat_bread(sb, b))) {
printk("bread in fat_access failed\n");
return 0;
}
- if ((first >> SECTOR_BITS) == (last >> SECTOR_BITS)) {
+ if ((first >> sb->s_blocksize_bits) == (last >> sb->s_blocksize_bits)) {
bh2 = bh;
} else {
if (!(bh2 = fat_bread(sb, b+1))) {
if (MSDOS_SB(sb)->fat_bits == 32) {
p_first = p_last = NULL; /* GCC needs that stuff */
next = CF_LE_L(((__u32 *) bh->b_data)[(first &
- (SECTOR_SIZE-1)) >> 2]);
+ (sb->s_blocksize - 1)) >> 2]);
/* Fscking Microsoft marketing department. Their "32" is 28. */
next &= 0xfffffff;
if (next >= 0xffffff7) next = -1;
} else if (MSDOS_SB(sb)->fat_bits == 16) {
p_first = p_last = NULL; /* GCC needs that stuff */
next = CF_LE_W(((__u16 *) bh->b_data)[(first &
- (SECTOR_SIZE-1)) >> 1]);
+ (sb->s_blocksize - 1)) >> 1]);
if (next >= 0xfff7) next = -1;
} else {
- p_first = &((__u8 *) bh->b_data)[first & (SECTOR_SIZE-1)];
- p_last = &((__u8 *) bh2->b_data)[(first+1) &
- (SECTOR_SIZE-1)];
+ p_first = &((__u8 *)bh->b_data)[first & (sb->s_blocksize - 1)];
+ p_last = &((__u8 *)bh2->b_data)[(first + 1) & (sb->s_blocksize - 1)];
if (nr & 1) next = ((*p_first >> 4) | (*p_last << 4)) & 0xfff;
else next = (*p_first+(*p_last << 8)) & 0xfff;
if (next >= 0xff7) next = -1;
}
if (new_value != -1) {
if (MSDOS_SB(sb)->fat_bits == 32) {
- ((__u32 *) bh->b_data)[(first & (SECTOR_SIZE-1)) >>
- 2] = CT_LE_L(new_value);
+ ((__u32 *)bh->b_data)[(first & (sb->s_blocksize - 1)) >> 2]
+ = CT_LE_L(new_value);
} else if (MSDOS_SB(sb)->fat_bits == 16) {
- ((__u16 *) bh->b_data)[(first & (SECTOR_SIZE-1)) >>
- 1] = CT_LE_W(new_value);
+ ((__u16 *)bh->b_data)[(first & (sb->s_blocksize - 1)) >> 1]
+ = CT_LE_W(new_value);
} else {
if (nr & 1) {
*p_first = (*p_first & 0xf) | (new_value << 4);
}
fat_mark_buffer_dirty(sb, bh);
for (copy = 1; copy < MSDOS_SB(sb)->fats; copy++) {
- b = MSDOS_SB(sb)->fat_start + (first >> SECTOR_BITS) +
- MSDOS_SB(sb)->fat_length * copy;
+ b = MSDOS_SB(sb)->fat_start + (first >> sb->s_blocksize_bits)
+ + MSDOS_SB(sb)->fat_length * copy;
if (!(c_bh = fat_bread(sb, b)))
break;
- memcpy(c_bh->b_data,bh->b_data,SECTOR_SIZE);
- fat_mark_buffer_dirty(sb, c_bh);
if (bh != bh2) {
if (!(c_bh2 = fat_bread(sb, b+1))) {
fat_brelse(sb, c_bh);
break;
}
- memcpy(c_bh2->b_data,bh2->b_data,SECTOR_SIZE);
+ memcpy(c_bh2->b_data, bh2->b_data, sb->s_blocksize);
+ fat_mark_buffer_dirty(sb, c_bh2);
fat_brelse(sb, c_bh2);
}
+ memcpy(c_bh->b_data, bh->b_data, sb->s_blocksize);
+ fat_mark_buffer_dirty(sb, c_bh);
fat_brelse(sb, c_bh);
}
}
if (initialized) {
spin_unlock(&fat_cache_lock);
return;
- }
+ }
fat_cache = &cache[0];
for (count = 0; count < FAT_CACHE; count++) {
cache[count].device = 0;
int default_fat_bmap(struct inode *inode,int sector)
{
- struct msdos_sb_info *sb=MSDOS_SB(inode->i_sb);
- int cluster,offset;
+ struct super_block *sb = inode->i_sb;
+ struct msdos_sb_info *sbi = MSDOS_SB(sb);
+ int cluster, offset, last_block;
- if ((sb->fat_bits != 32) &&
+ if ((sbi->fat_bits != 32) &&
(inode->i_ino == MSDOS_ROOT_INO || (S_ISDIR(inode->i_mode) &&
!MSDOS_I(inode)->i_start))) {
- if (sector >= sb->dir_entries >> MSDOS_DPS_BITS)
+ if (sector >= sbi->dir_entries >> sbi->dir_per_block_bits)
return 0;
- return sector+sb->dir_start;
+ return sector + sbi->dir_start;
}
- if (sector >= (MSDOS_I(inode)->mmu_private+511)>>9)
+ last_block = (MSDOS_I(inode)->mmu_private + (sb->s_blocksize - 1))
+ >> sb->s_blocksize_bits;
+ if (sector >= last_block)
return 0;
- cluster = sector/sb->cluster_size;
- offset = sector % sb->cluster_size;
- if (!(cluster = fat_get_cluster(inode,cluster))) return 0;
- return (cluster-2)*sb->cluster_size+sb->data_start+offset;
+
+ cluster = sector / sbi->cluster_size;
+ offset = sector % sbi->cluster_size;
+ if (!(cluster = fat_get_cluster(inode, cluster)))
+ return 0;
+
+ return (cluster - 2) * sbi->cluster_size + sbi->data_start + offset;
}
fat_clusters_flush(inode->i_sb);
}
}
- inode->i_blocks -= MSDOS_SB(inode->i_sb)->cluster_size;
+ inode->i_blocks -= (1 << MSDOS_SB(inode->i_sb)->cluster_bits) / 512;
}
unlock_fat(inode->i_sb);
return 0;
}
-int fat_get_block(struct inode *inode, long iblock, struct buffer_head *bh_result, int create) {
+int fat_get_block(struct inode *inode, long iblock, struct buffer_head *bh_result, int create)
+{
+ struct super_block *sb = inode->i_sb;
unsigned long phys;
+
phys = fat_bmap(inode, iblock);
if (phys) {
bh_result->b_dev = inode->i_dev;
}
if (!create)
return 0;
- if (iblock<<9 != MSDOS_I(inode)->mmu_private) {
+ if (iblock << sb->s_blocksize_bits != MSDOS_I(inode)->mmu_private) {
BUG();
return -EIO;
}
if (fat_add_cluster(inode))
return -ENOSPC;
}
- MSDOS_I(inode)->mmu_private += 512;
- phys=fat_bmap(inode, iblock);
+ MSDOS_I(inode)->mmu_private += sb->s_blocksize;
+ phys = fat_bmap(inode, iblock);
if (!phys)
BUG();
bh_result->b_dev = inode->i_dev;
return /* -EPERM */;
if (IS_IMMUTABLE(inode))
return /* -EPERM */;
- cluster = SECTOR_SIZE*sbi->cluster_size;
+ cluster = 1 << sbi->cluster_bits;
/*
* This protects against truncating a file bigger than it was then
* trying to write into the hole.
if (MSDOS_I(inode)->mmu_private > inode->i_size)
MSDOS_I(inode)->mmu_private = inode->i_size;
- fat_free(inode,(inode->i_size+(cluster-1))>>sbi->cluster_bits);
+ fat_free(inode, (inode->i_size + (cluster - 1)) >> sbi->cluster_bits);
MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
inode->i_ctime = inode->i_mtime = CURRENT_TIME;
mark_inode_dirty(inode);
}
-static int parse_options(char *options,int *fat, int *blksize, int *debug,
+static int parse_options(char *options,int *fat, int *debug,
struct fat_mount_options *opts,
char *cvf_format, char *cvf_options)
{
else opts->quiet = 1;
}
else if (!strcmp(this_char,"blocksize")) {
- if (!value || !*value) ret = 0;
- else {
- *blksize = simple_strtoul(value,&value,0);
- if (*value || (*blksize != 512 &&
- *blksize != 1024 && *blksize != 2048))
- ret = 0;
- }
+ printk("FAT: blocksize option is obsolete, "
+ "not supported now\n");
}
else if (!strcmp(this_char,"sys_immutable")) {
if (value) ret = 0;
MSDOS_I(inode)->i_start = sbi->root_cluster;
if ((nr = MSDOS_I(inode)->i_start) != 0) {
while (nr != -1) {
- inode->i_size += SECTOR_SIZE*sbi->cluster_size;
- if (!(nr = fat_access(sb,nr,-1))) {
+ inode->i_size += 1 << sbi->cluster_bits;
+ if (!(nr = fat_access(sb, nr, -1))) {
printk("Directory %ld: bad FAT\n",
inode->i_ino);
break;
}
} else {
MSDOS_I(inode)->i_start = 0;
- inode->i_size = sbi->dir_entries*
- sizeof(struct msdos_dir_entry);
+ inode->i_size = sbi->dir_entries * sizeof(struct msdos_dir_entry);
}
- inode->i_blksize = sbi->cluster_size* SECTOR_SIZE;
- inode->i_blocks =
- ((inode->i_size+inode->i_blksize-1)>>sbi->cluster_bits) *
- sbi->cluster_size;
+ inode->i_blksize = 1 << sbi->cluster_bits;
+ inode->i_blocks = ((inode->i_size + inode->i_blksize - 1)
+ & ~(inode->i_blksize - 1)) / 512;
MSDOS_I(inode)->i_logstart = 0;
MSDOS_I(inode)->mmu_private = inode->i_size;
struct fat_boot_sector *b;
struct msdos_sb_info *sbi = MSDOS_SB(sb);
char *p;
- int data_sectors,logical_sector_size,sector_mult,fat_clusters=0;
- int debug,error,fat,cp;
- int blksize;
- int fat32;
+ int logical_sector_size, hard_blksize, fat_clusters = 0;
+ unsigned int total_sectors, rootdir_sectors;
+ int fat32, debug, error, fat, cp;
struct fat_mount_options opts;
char buf[50];
int i;
sb->s_maxbytes = MAX_NON_LFS;
sb->s_op = &fat_sops;
- blksize = get_hardsect_size(sb->s_dev);
- if (!blksize)
- blksize = 512;
- if (blksize != 512)
- printk ("MSDOS: Hardware sector size is %d\n",blksize);
+
+ hard_blksize = get_hardsect_size(sb->s_dev);
+ if (!hard_blksize)
+ hard_blksize = 512;
+ if (hard_blksize != 512)
+ printk("MSDOS: Hardware sector size is %d\n", hard_blksize);
opts.isvfat = sbi->options.isvfat;
- if (!parse_options((char *) data, &fat, &blksize, &debug, &opts,
- cvf_format, cvf_options)
- || (blksize != 512 && blksize != 1024 && blksize != 2048))
+ if (!parse_options((char *) data, &fat, &debug, &opts,
+ cvf_format, cvf_options))
goto out_fail;
/* N.B. we should parse directly into the sb structure */
memcpy(&(sbi->options), &opts, sizeof(struct fat_mount_options));
fat_cache_init();
- if( blksize > 1024 )
- {
- /* Force the superblock to a larger size here. */
- sb->s_blocksize = blksize;
- set_blocksize(sb->s_dev, blksize);
- }
- else
- {
- /* The first read is always 1024 bytes */
- sb->s_blocksize = 1024;
- set_blocksize(sb->s_dev, 1024);
- }
+
+ sb->s_blocksize = hard_blksize;
+ set_blocksize(sb->s_dev, hard_blksize);
bh = bread(sb->s_dev, 0, sb->s_blocksize);
- if (bh == NULL || !buffer_uptodate(bh)) {
+ if (bh == NULL) {
brelse (bh);
goto out_no_bread;
}
* (by Drew Eckhardt)
*/
-#define ROUND_TO_MULTIPLE(n,m) ((n) && (m) ? (n)+(m)-1-((n)-1)%(m) : 0)
- /* don't divide by zero */
b = (struct fat_boot_sector *) bh->b_data;
logical_sector_size =
CF_LE_W(get_unaligned((unsigned short *) &b->sector_size));
- sector_mult = logical_sector_size >> SECTOR_BITS;
- sbi->cluster_size = b->cluster_size*sector_mult;
- if (!sbi->cluster_size || (sbi->cluster_size & (sbi->cluster_size-1))) {
- printk("fatfs: bogus cluster size\n");
+ if (!logical_sector_size
+ || (logical_sector_size & (logical_sector_size - 1))) {
+ printk("fatfs: bogus logical sector size %d\n",
+ logical_sector_size);
brelse(bh);
goto out_invalid;
}
- for (sbi->cluster_bits=0;
- 1<<sbi->cluster_bits<sbi->cluster_size;
- sbi->cluster_bits++)
- ;
- sbi->cluster_bits += SECTOR_BITS;
+
+ sbi->cluster_size = b->cluster_size;
+ if (!sbi->cluster_size || (sbi->cluster_size & (sbi->cluster_size - 1))) {
+ printk("fatfs: bogus cluster size %d\n", sbi->cluster_size);
+ brelse(bh);
+ goto out_invalid;
+ }
+
+ sbi->cluster_bits = ffs(logical_sector_size * sbi->cluster_size) - 1;
sbi->fats = b->fats;
- sbi->fat_start = CF_LE_W(b->reserved)*sector_mult;
+ sbi->fat_start = CF_LE_W(b->reserved);
if (!b->fat_length && b->fat32_length) {
struct fat_boot_fsinfo *fsinfo;
+ struct buffer_head *fsinfo_bh;
+ int fsinfo_block, fsinfo_offset;
/* Must be FAT32 */
fat32 = 1;
- sbi->fat_length= CF_LE_L(b->fat32_length)*sector_mult;
+ sbi->fat_length = CF_LE_L(b->fat32_length);
sbi->root_cluster = CF_LE_L(b->root_cluster);
+ sbi->fsinfo_sector = CF_LE_W(b->info_sector);
/* MC - if info_sector is 0, don't multiply by 0 */
- if(CF_LE_W(b->info_sector) == 0) {
- sbi->fsinfo_offset =
- logical_sector_size + 0x1e0;
- } else {
- sbi->fsinfo_offset =
- (CF_LE_W(b->info_sector) * logical_sector_size)
- + 0x1e0;
- }
- if (sbi->fsinfo_offset + sizeof(struct fat_boot_fsinfo) > sb->s_blocksize) {
- printk("fat_read_super: Bad fsinfo_offset\n");
- brelse(bh);
- goto out_invalid;
+ if (sbi->fsinfo_sector == 0)
+ sbi->fsinfo_sector = 1;
+
+ fsinfo_block =
+ (sbi->fsinfo_sector * logical_sector_size) / hard_blksize;
+ fsinfo_offset =
+ (sbi->fsinfo_sector * logical_sector_size) % hard_blksize;
+ fsinfo_bh = bh;
+ if (bh->b_blocknr != fsinfo_block) {
+ fsinfo_bh = bread(sb->s_dev, fsinfo_block, hard_blksize);
+ if (fsinfo_bh == NULL) {
+ printk("FAT: bread failed, fsinfo block %d\n",
+ fsinfo_block);
+ brelse(bh);
+ goto out_invalid;
+ }
}
- fsinfo = (struct fat_boot_fsinfo *)
- &bh->b_data[sbi->fsinfo_offset];
- if (CF_LE_L(fsinfo->signature) != 0x61417272) {
- printk("fat_read_super: Did not find valid FSINFO "
- "signature. Found 0x%x\n",
- CF_LE_L(fsinfo->signature));
+ fsinfo = (struct fat_boot_fsinfo *)&fsinfo_bh->b_data[fsinfo_offset];
+ if (!IS_FSINFO(fsinfo)) {
+ printk("FAT: Did not find valid FSINFO signature.\n"
+ "Found signature1 0x%x signature2 0x%x sector=%ld.\n",
+ CF_LE_L(fsinfo->signature1),
+ CF_LE_L(fsinfo->signature2),
+ sbi->fsinfo_sector);
} else {
sbi->free_clusters = CF_LE_L(fsinfo->free_clusters);
}
+
+ if (bh->b_blocknr != fsinfo_block)
+ brelse(fsinfo_bh);
} else {
fat32 = 0;
- sbi->fat_length = CF_LE_W(b->fat_length)*sector_mult;
+ sbi->fat_length = CF_LE_W(b->fat_length);
sbi->root_cluster = 0;
sbi->free_clusters = -1; /* Don't know yet */
}
- sbi->dir_start= CF_LE_W(b->reserved)*sector_mult+
- b->fats*sbi->fat_length;
+
+ sbi->dir_per_block = logical_sector_size / sizeof(struct msdos_dir_entry);
+ sbi->dir_per_block_bits = ffs(sbi->dir_per_block) - 1;
+
+ sbi->dir_start = sbi->fat_start + sbi->fats * sbi->fat_length;
sbi->dir_entries =
- CF_LE_W(get_unaligned((unsigned short *) &b->dir_entries));
- sbi->data_start = sbi->dir_start+ROUND_TO_MULTIPLE((
- sbi->dir_entries << MSDOS_DIR_BITS) >> SECTOR_BITS,
- sector_mult);
- data_sectors = CF_LE_W(get_unaligned((unsigned short *) &b->sectors));
- if (!data_sectors) {
- data_sectors = CF_LE_L(b->total_sect);
- }
- data_sectors = data_sectors * sector_mult - sbi->data_start;
- error = !b->cluster_size || !sector_mult;
+ CF_LE_W(get_unaligned((unsigned short *)&b->dir_entries));
+ rootdir_sectors = sbi->dir_entries
+ * sizeof(struct msdos_dir_entry) / logical_sector_size;
+ sbi->data_start = sbi->dir_start + rootdir_sectors;
+ total_sectors = CF_LE_W(get_unaligned((unsigned short *)&b->sectors));
+ if (total_sectors == 0)
+ total_sectors = CF_LE_L(b->total_sect);
+ sbi->clusters = (total_sectors - sbi->data_start) / sbi->cluster_size;
+
+ error = 0;
if (!error) {
- sbi->clusters = b->cluster_size ? data_sectors/
- b->cluster_size/sector_mult : 0;
sbi->fat_bits = fat32 ? 32 :
(fat ? fat :
(sbi->clusters > MSDOS_FAT12 ? 16 : 12));
- fat_clusters = sbi->fat_length*SECTOR_SIZE*8/
- sbi->fat_bits;
- error = !sbi->fats || (sbi->dir_entries &
- (MSDOS_DPS-1)) || sbi->clusters+2 > fat_clusters+
- MSDOS_MAX_EXTRA || (logical_sector_size & (SECTOR_SIZE-1))
- || !b->secs_track || !b->heads;
+ fat_clusters =
+ sbi->fat_length * logical_sector_size * 8 / sbi->fat_bits;
+ error = !sbi->fats || (sbi->dir_entries & (sbi->dir_per_block - 1))
+ || sbi->clusters + 2 > fat_clusters + MSDOS_MAX_EXTRA
+ || logical_sector_size < 512
+ || PAGE_CACHE_SIZE < logical_sector_size
+ || !b->secs_track || !b->heads;
}
brelse(bh);
- set_blocksize(sb->s_dev, blksize);
- /*
- This must be done after the brelse because the bh is a dummy
- allocated by fat_bread (see buffer.c)
- */
- sb->s_blocksize = blksize; /* Using this small block size solves */
- /* the misfit with buffer cache and cluster */
- /* because clusters (DOS) are often aligned */
- /* on odd sectors. */
- sb->s_blocksize_bits = blksize == 512 ? 9 : (blksize == 1024 ? 10 : 11);
+
+ sb->s_blocksize = logical_sector_size;
+ sb->s_blocksize_bits = ffs(logical_sector_size) - 1;
+ if (sb->s_blocksize >= hard_blksize) {
+ set_blocksize(sb->s_dev, sb->s_blocksize);
+ sbi->cvf_format = &default_cvf;
+ } else {
+ set_blocksize(sb->s_dev, hard_blksize);
+ sbi->cvf_format = &bigblock_cvf;
+ }
+
if (!strcmp(cvf_format,"none"))
i = -1;
else
i = detect_cvf(sb,cvf_format);
if (i >= 0)
error = cvf_formats[i]->mount_cvf(sb,cvf_options);
- else if (sb->s_blocksize == 512)
- sbi->cvf_format = &default_cvf;
- else
- sbi->cvf_format = &bigblock_cvf;
if (error || debug) {
/* The MSDOS_CAN_BMAP is obsolete, but left just to remember */
printk("[MS-DOS FS Rel. 12,FAT %d,check=%c,conv=%c,"
MSDOS_CAN_BMAP(sbi) ? ",bmap" : "");
printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%ld,ds=%ld,de=%d,data=%ld,"
"se=%d,ts=%ld,ls=%d,rc=%ld,fc=%u]\n",
- b->media,sbi->cluster_size,
- sbi->fats,sbi->fat_start,
- sbi->fat_length,
+ b->media,sbi->cluster_size,
+ sbi->fats,sbi->fat_start,
+ sbi->fat_length,
sbi->dir_start,sbi->dir_entries,
sbi->data_start,
CF_LE_W(*(unsigned short *) &b->sectors),
(unsigned long)b->total_sect,logical_sector_size,
sbi->root_cluster,sbi->free_clusters);
- printk ("Transaction block size = %d\n",blksize);
+ printk ("Transaction block size = %d\n", hard_blksize);
}
- if (i<0) if (sbi->clusters+2 > fat_clusters)
- sbi->clusters = fat_clusters-2;
+ if (i < 0)
+ if (sbi->clusters + 2 > fat_clusters)
+ sbi->clusters = fat_clusters - 2;
if (error)
goto out_invalid;
}
if(sbi->private_data)
kfree(sbi->private_data);
- sbi->private_data=NULL;
+ sbi->private_data = NULL;
return NULL;
}
}
unlock_fat(sb);
buf->f_type = sb->s_magic;
- buf->f_bsize = MSDOS_SB(sb)->cluster_size*SECTOR_SIZE;
+ buf->f_bsize = 1 << MSDOS_SB(sb)->cluster_bits;
buf->f_blocks = MSDOS_SB(sb)->clusters;
buf->f_bfree = free;
buf->f_bavail = free;
#endif
if ((nr = MSDOS_I(inode)->i_start) != 0)
while (nr != -1) {
- inode->i_size += SECTOR_SIZE*sbi->cluster_size;
- if (!(nr = fat_access(sb,nr,-1))) {
+ inode->i_size += 1 << sbi->cluster_bits;
+ if (!(nr = fat_access(sb, nr, -1))) {
printk("Directory %ld: bad FAT\n",
inode->i_ino);
break;
inode->i_flags |= S_IMMUTABLE;
MSDOS_I(inode)->i_attrs = de->attr & ATTR_UNUSED;
/* this is as close to the truth as we can get ... */
- inode->i_blksize = sbi->cluster_size*SECTOR_SIZE;
- inode->i_blocks =
- ((inode->i_size+inode->i_blksize-1)>>sbi->cluster_bits) *
- sbi->cluster_size;
+ inode->i_blksize = 1 << sbi->cluster_bits;
+ inode->i_blocks = ((inode->i_size + inode->i_blksize - 1)
+ & ~(inode->i_blksize - 1)) / 512;
inode->i_mtime = inode->i_atime =
- date_dos2unix(CF_LE_W(de->time),CF_LE_W(de->date));
+ date_dos2unix(CF_LE_W(de->time),CF_LE_W(de->date));
inode->i_ctime =
MSDOS_SB(sb)->options.isvfat
? date_dos2unix(CF_LE_W(de->ctime),CF_LE_W(de->cdate))
return;
}
lock_kernel();
- if (!(bh = fat_bread(sb, i_pos >> MSDOS_DPB_BITS))) {
+ if (!(bh = fat_bread(sb, i_pos >> MSDOS_SB(sb)->dir_per_block_bits))) {
printk("dev = %s, ino = %d\n", kdevname(inode->i_dev), i_pos);
fat_fs_panic(sb, "msdos_write_inode: unable to read i-node block");
unlock_kernel();
}
raw_entry = &((struct msdos_dir_entry *) (bh->b_data))
- [i_pos & (MSDOS_DPB-1)];
+ [i_pos & (MSDOS_SB(sb)->dir_per_block - 1)];
if (S_ISDIR(inode->i_mode)) {
raw_entry->attr = ATTR_DIR;
raw_entry->size = 0;
/* XXX: Need to write one per FSINFO block. Currently only writes 1 */
void fat_clusters_flush(struct super_block *sb)
{
- int offset;
struct buffer_head *bh;
struct fat_boot_fsinfo *fsinfo;
- /* The fat32 boot fs info is at offset 0x3e0 by observation */
- offset = MSDOS_SB(sb)->fsinfo_offset;
- bh = fat_bread(sb, (offset >> SECTOR_BITS));
+ bh = fat_bread(sb, MSDOS_SB(sb)->fsinfo_sector);
if (bh == NULL) {
printk("FAT bread failed in fat_clusters_flush\n");
return;
}
- fsinfo = (struct fat_boot_fsinfo *)
- &bh->b_data[offset & (SECTOR_SIZE-1)];
+ fsinfo = (struct fat_boot_fsinfo *)bh->b_data;
/* Sanity check */
- if (CF_LE_L(fsinfo->signature) != 0x61417272) {
- printk("fat_clusters_flush: Did not find valid FSINFO signature. Found 0x%x. offset=0x%x\n", CF_LE_L(fsinfo->signature), offset);
- fat_brelse(sb, bh);
+ if (!IS_FSINFO(fsinfo)) {
+ printk("FAT: Did not find valid FSINFO signature.\n"
+ "Found signature1 0x%x signature2 0x%x sector=%ld.\n",
+ CF_LE_L(fsinfo->signature1), CF_LE_L(fsinfo->signature2),
+ MSDOS_SB(sb)->fsinfo_sector);
return;
}
fsinfo->free_clusters = CF_LE_L(MSDOS_SB(sb)->free_clusters);
struct super_block *sb = inode->i_sb;
int count,nr,limit,last,curr,file_cluster;
int res = -ENOSPC;
- int cluster_size = MSDOS_SB(sb)->cluster_size;
if (!MSDOS_SB(sb)->free_clusters) return res;
lock_fat(sb);
if (MSDOS_SB(sb)->fat_bits == 32)
fat_clusters_flush(sb);
unlock_fat(sb);
- last = 0;
+
/* We must locate the last cluster of the file to add this
new one (nr) to the end of the link list (the FAT).
use last to plug the nr cluster. We will use file_cluster to
update the cache.
*/
- file_cluster = 0;
+ last = file_cluster = 0;
if ((curr = MSDOS_I(inode)->i_start) != 0) {
fat_cache_lookup(inode,INT_MAX,&last,&curr);
file_cluster = last;
}
}
}
- if (last) fat_access(sb,last,nr);
- else {
+ if (last) {
+ fat_access(sb, last, nr);
+ fat_cache_add(inode, file_cluster, nr);
+ } else {
MSDOS_I(inode)->i_start = nr;
MSDOS_I(inode)->i_logstart = nr;
mark_inode_dirty(inode);
}
- fat_cache_add(inode,file_cluster,nr);
- inode->i_blocks += cluster_size;
+ inode->i_blocks += (1 << MSDOS_SB(sb)->cluster_bits) / 512;
return 0;
}
int cluster_size = MSDOS_SB(sb)->cluster_size;
if (MSDOS_SB(sb)->fat_bits != 32) {
- if (inode->i_ino == MSDOS_ROOT_INO) return res;
+ if (inode->i_ino == MSDOS_ROOT_INO)
+ return res;
}
- if (!MSDOS_SB(sb)->free_clusters) return res;
+ if (!MSDOS_SB(sb)->free_clusters)
+ return res;
+
lock_fat(sb);
+
limit = MSDOS_SB(sb)->clusters;
nr = limit; /* to keep GCC happy */
for (count = 0; count < limit; count++) {
- nr = ((count+MSDOS_SB(sb)->prev_free) % limit)+2;
- if (fat_access(sb,nr,-1) == 0) break;
+ nr = ((count + MSDOS_SB(sb)->prev_free) % limit) + 2;
+ if (fat_access(sb, nr, -1) == 0)
+ break;
}
- PRINTK (("cnt = %d --",count));
+ PRINTK (("cnt = %d --", count));
#ifdef DEBUG
-printk("free cluster: %d\n",nr);
+ printk("free cluster: %d\n", nr);
#endif
- MSDOS_SB(sb)->prev_free = (count+MSDOS_SB(sb)->prev_free+1) % limit;
if (count >= limit) {
MSDOS_SB(sb)->free_clusters = 0;
unlock_fat(sb);
return res;
}
- fat_access(sb,nr,EOF_FAT(sb));
+
+ MSDOS_SB(sb)->prev_free = (count + MSDOS_SB(sb)->prev_free + 1) % limit;
+ fat_access(sb, nr, EOF_FAT(sb));
if (MSDOS_SB(sb)->free_clusters != -1)
MSDOS_SB(sb)->free_clusters--;
if (MSDOS_SB(sb)->fat_bits == 32)
fat_clusters_flush(sb);
+
unlock_fat(sb);
+
#ifdef DEBUG
-printk("set to %x\n",fat_access(sb,nr,-1));
+ printk("set to %x\n", fat_access(sb, nr, -1));
#endif
- last = 0;
+
/* We must locate the last cluster of the file to add this
new one (nr) to the end of the link list (the FAT).
use last to plug the nr cluster. We will use file_cluster to
update the cache.
*/
- file_cluster = 0;
+ last = file_cluster = 0;
if ((curr = MSDOS_I(inode)->i_start) != 0) {
- fat_cache_lookup(inode,INT_MAX,&last,&curr);
+ fat_cache_lookup(inode, INT_MAX, &last, &curr);
file_cluster = last;
while (curr && curr != -1){
PRINTK (("."));
file_cluster++;
- if (!(curr = fat_access(sb,
- last = curr,-1))) {
+ if (!(curr = fat_access(sb, last = curr, -1))) {
fat_fs_panic(sb,"File without EOF");
return res;
}
PRINTK ((" -- "));
}
#ifdef DEBUG
-printk("last = %d\n",last);
+ printk("last = %d\n", last);
#endif
- if (last) fat_access(sb,last,nr);
+ if (last)
+ fat_access(sb, last, nr);
else {
MSDOS_I(inode)->i_start = nr;
MSDOS_I(inode)->i_logstart = nr;
mark_inode_dirty(inode);
}
#ifdef DEBUG
-if (last) printk("next set to %d\n",fat_access(sb,last,-1));
+ if (last)
+ printk("next set to %d\n",fat_access(sb, last, -1));
#endif
- sector = MSDOS_SB(sb)->data_start+(nr-2)*cluster_size;
+ sector = MSDOS_SB(sb)->data_start + (nr - 2) * cluster_size;
last_sector = sector + cluster_size;
- if (MSDOS_SB(sb)->cvf_format &&
- MSDOS_SB(sb)->cvf_format->zero_out_cluster)
- MSDOS_SB(sb)->cvf_format->zero_out_cluster(inode,nr);
- else
- for ( ; sector < last_sector; sector++) {
- #ifdef DEBUG
- printk("zeroing sector %d\n",sector);
- #endif
- if (!(bh = fat_getblk(sb, sector)))
- printk("getblk failed\n");
- else {
- memset(bh->b_data,0,SECTOR_SIZE);
- fat_set_uptodate(sb, bh, 1);
- fat_mark_buffer_dirty(sb, bh);
- if (!res)
- res=bh;
- else
- fat_brelse(sb, bh);
+ if (MSDOS_SB(sb)->cvf_format && MSDOS_SB(sb)->cvf_format->zero_out_cluster)
+ MSDOS_SB(sb)->cvf_format->zero_out_cluster(inode, nr);
+ else {
+ for ( ; sector < last_sector; sector++) {
+#ifdef DEBUG
+ printk("zeroing sector %d\n", sector);
+#endif
+ if (!(bh = fat_getblk(sb, sector)))
+ printk("getblk failed\n");
+ else {
+ memset(bh->b_data, 0, sb->s_blocksize);
+ fat_set_uptodate(sb, bh, 1);
+ fat_mark_buffer_dirty(sb, bh);
+ if (!res)
+ res = bh;
+ else
+ fat_brelse(sb, bh);
+ }
}
}
- if (file_cluster != inode->i_blocks/cluster_size){
- printk ("file_cluster badly computed!!! %d <> %ld\n"
- ,file_cluster,inode->i_blocks/cluster_size);
+ if (file_cluster
+ != inode->i_blocks / cluster_size / (sb->s_blocksize / 512)) {
+ printk ("file_cluster badly computed!!! %d <> %ld\n",
+ file_cluster,
+ inode->i_blocks / cluster_size / (sb->s_blocksize / 512));
}else{
- fat_cache_add(inode,file_cluster,nr);
+ fat_cache_add(inode, file_cluster, nr);
}
- inode->i_blocks += cluster_size;
- if (inode->i_size & (SECTOR_SIZE-1)) {
- fat_fs_panic(sb,"Odd directory size");
- inode->i_size = (inode->i_size+SECTOR_SIZE) &
- ~(SECTOR_SIZE-1);
+ inode->i_blocks += (1 << MSDOS_SB(sb)->cluster_bits) / 512;
+ if (inode->i_size & (sb->s_blocksize - 1)) {
+ fat_fs_panic(sb, "Odd directory size");
+ inode->i_size = (inode->i_size + sb->s_blocksize) &
+ ~(sb->s_blocksize - 1);
}
- inode->i_size += SECTOR_SIZE*cluster_size;
- MSDOS_I(inode)->mmu_private += SECTOR_SIZE*cluster_size;
+ inode->i_size += 1 << MSDOS_SB(sb)->cluster_bits;
+ MSDOS_I(inode)->mmu_private += 1 << MSDOS_SB(sb)->cluster_bits;
mark_inode_dirty(inode);
return res;
}
struct msdos_dir_entry **de, int *ino)
{
struct super_block *sb = dir->i_sb;
+ struct msdos_sb_info *sbi = MSDOS_SB(sb);
int sector, offset;
while (1) {
if (*bh)
fat_brelse(sb, *bh);
*bh = NULL;
- if ((sector = fat_bmap(dir,offset >> SECTOR_BITS)) == -1)
+ if ((sector = fat_bmap(dir,offset >> sb->s_blocksize_bits)) == -1)
return -1;
PRINTK (("get_entry sector %d %p\n",sector,*bh));
PRINTK (("get_entry sector apres brelse\n"));
continue;
}
PRINTK (("get_entry apres sread\n"));
- *de = (struct msdos_dir_entry *) ((*bh)->b_data+(offset &
- (SECTOR_SIZE-1)));
- *ino = (sector << MSDOS_DPS_BITS)+((offset & (SECTOR_SIZE-1)) >>
- MSDOS_DIR_BITS);
+
+ offset &= sb->s_blocksize - 1;
+ *de = (struct msdos_dir_entry *) ((*bh)->b_data + offset);
+ *ino = (sector << sbi->dir_per_block_bits) + (offset >> MSDOS_DIR_BITS);
+
return 0;
}
}
if (!(bh = fat_bread(sb,sector)))
return -EIO;
data = (struct msdos_dir_entry *) bh->b_data;
- for (entry = 0; entry < MSDOS_DPS; entry++) {
+ for (entry = 0; entry < MSDOS_SB(sb)->dir_per_block; entry++) {
/* RSS_COUNT: if (data[entry].name == name) done=true else done=false. */
if (name) {
RSS_NAME
}
}
if (done) {
- if (ino) *ino = sector*MSDOS_DPS+entry;
+ if (ino)
+ *ino = sector * MSDOS_SB(sb)->dir_per_block + entry;
start = CF_LE_W(data[entry].start);
if (MSDOS_SB(sb)->fat_bits == 32) {
start |= (CF_LE_W(data[entry].starthi) << 16);
{
int count,cluster;
- for (count = 0; count < MSDOS_SB(sb)->dir_entries/MSDOS_DPS; count++) {
+ for (count = 0;
+ count < MSDOS_SB(sb)->dir_entries / MSDOS_SB(sb)->dir_per_block;
+ count++) {
if ((cluster = raw_scan_sector(sb,MSDOS_SB(sb)->dir_start+count,
- name,number,ino,res_bh,res_de)) >= 0) return cluster;
+ name,number,ino,res_bh,res_de)) >= 0)
+ return cluster;
}
return -ENOENT;
}
int *number, int *ino, struct buffer_head **res_bh,
struct msdos_dir_entry **res_de)
{
- if (start) return raw_scan_nonroot
- (sb,start,name,number,ino,res_bh,res_de);
- else return raw_scan_root
- (sb,name,number,ino,res_bh,res_de);
+ if (start)
+ return raw_scan_nonroot(sb,start,name,number,ino,res_bh,res_de);
+ else
+ return raw_scan_root(sb,name,number,ino,res_bh,res_de);
}
-
/*
* fat_parent_ino returns the inode number of the parent directory of dir.
* File creation has to be deferred while fat_parent_ino is running to
return nr;
}
-
/*
* fat_subdirs counts the number of sub-directories of dir. It can be run
* on directories being created.
struct vxfs_typed_dev4 *typ4 = (struct vxfs_typed_dev4 *)typ;
printk(KERN_INFO "\n\nTYPED_DEV4 detected!\n");
printk(KERN_INFO "block: %Ld\tsize: %Ld\tdev: %d\n",
- typ4->vd4_block, typ4->vd4_size, typ4->vd4_dev);
+ (long long)typ4->vd4_block, (long long)typ4->vd4_size, typ4->vd4_dev);
goto fail;
}
default:
struct vxfs_typed_dev4 *typ4 = (struct vxfs_typed_dev4 *)typ;
printk(KERN_INFO "\n\nTYPED_DEV4 detected!\n");
printk(KERN_INFO "block: %Ld\tsize: %Ld\tdev: %d\n",
- typ4->vd4_block, typ4->vd4_size, typ4->vd4_dev);
+ (long long)typ4->vd4_block, (long long)typ4->vd4_size, typ4->vd4_dev);
return 0;
}
default:
ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL);
if (!ent->data) {
kfree(ent);
+ ent = NULL;
goto out;
}
strcpy((char*)ent->data,dest);
static LIST_HEAD(vfsmntlist);
+static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd)
+{
+ old_nd->dentry = mnt->mnt_mountpoint;
+ old_nd->mnt = mnt->mnt_parent;
+ mnt->mnt_parent = mnt;
+ mnt->mnt_mountpoint = mnt->mnt_root;
+ list_del_init(&mnt->mnt_child);
+ list_del_init(&mnt->mnt_clash);
+}
+
+static void attach_mnt(struct vfsmount *mnt, struct nameidata *nd)
+{
+ mnt->mnt_parent = mntget(nd->mnt);
+ mnt->mnt_mountpoint = dget(nd->dentry);
+ list_add(&mnt->mnt_clash, &nd->dentry->d_vfsmnt);
+ list_add(&mnt->mnt_child, &nd->mnt->mnt_mounts);
+}
+
/**
* add_vfsmnt - add a new mount node
* @nd: location of mountpoint or %NULL if we want a root node
if (nd && !IS_ROOT(nd->dentry) && d_unhashed(nd->dentry))
goto fail;
mnt->mnt_root = dget(root);
- mnt->mnt_mountpoint = nd ? dget(nd->dentry) : dget(root);
- mnt->mnt_parent = nd ? mntget(nd->mnt) : mnt;
if (nd) {
- list_add(&mnt->mnt_child, &nd->mnt->mnt_mounts);
- list_add(&mnt->mnt_clash, &nd->dentry->d_vfsmnt);
+ attach_mnt(mnt, nd);
} else {
+ mnt->mnt_mountpoint = mnt->mnt_root;
+ mnt->mnt_parent = mnt;
INIT_LIST_HEAD(&mnt->mnt_child);
INIT_LIST_HEAD(&mnt->mnt_clash);
}
}
static void move_vfsmnt(struct vfsmount *mnt,
- struct dentry *mountpoint,
- struct vfsmount *parent,
+ struct nameidata *nd,
const char *dev_name)
{
- struct dentry *old_mountpoint;
- struct vfsmount *old_parent;
+ struct nameidata parent_nd;
char *new_devname = NULL;
if (dev_name) {
}
spin_lock(&dcache_lock);
- old_mountpoint = mnt->mnt_mountpoint;
- old_parent = mnt->mnt_parent;
+ detach_mnt(mnt, &parent_nd);
+ attach_mnt(mnt, nd);
- /* flip names */
if (new_devname) {
if (mnt->mnt_devname)
kfree(mnt->mnt_devname);
mnt->mnt_devname = new_devname;
}
-
- /* flip the linkage */
- mnt->mnt_mountpoint = dget(mountpoint);
- mnt->mnt_parent = parent ? mntget(parent) : mnt;
- list_del(&mnt->mnt_clash);
- list_del(&mnt->mnt_child);
- if (parent) {
- list_add(&mnt->mnt_child, &parent->mnt_mounts);
- list_add(&mnt->mnt_clash, &mountpoint->d_vfsmnt);
- } else {
- INIT_LIST_HEAD(&mnt->mnt_child);
- INIT_LIST_HEAD(&mnt->mnt_clash);
- }
spin_unlock(&dcache_lock);
/* put the old stuff */
- dput(old_mountpoint);
- if (old_parent != mnt)
- mntput(old_parent);
+ if (parent_nd.mnt != mnt)
+ path_release(&parent_nd);
}
-/*
- * Called with spinlock held, releases it.
- */
-static void remove_vfsmnt(struct vfsmount *mnt)
+static void kill_super(struct super_block *);
+
+void __mntput(struct vfsmount *mnt)
{
- /* First of all, remove it from all lists */
- list_del(&mnt->mnt_instances);
- list_del(&mnt->mnt_clash);
- list_del(&mnt->mnt_list);
- list_del(&mnt->mnt_child);
- spin_unlock(&dcache_lock);
- /* Now we can work safely */
- if (mnt->mnt_parent != mnt)
- mntput(mnt->mnt_parent);
+ struct super_block *sb = mnt->mnt_sb;
- dput(mnt->mnt_mountpoint);
dput(mnt->mnt_root);
+ spin_lock(&dcache_lock);
+ list_del(&mnt->mnt_instances);
+ spin_unlock(&dcache_lock);
if (mnt->mnt_devname)
kfree(mnt->mnt_devname);
kfree(mnt);
+ kill_super(sb);
}
struct file_system_type *fs = sb->s_type;
struct super_operations *sop = sb->s_op;
+ spin_lock(&dcache_lock);
+ if (!list_empty(&sb->s_mounts)) {
+ spin_unlock(&dcache_lock);
+ return;
+ }
+ spin_unlock(&dcache_lock);
down_write(&sb->s_umount);
sb->s_root = NULL;
/* Need to clean after the sucker */
return mnt;
}
-/* Call only after unregister_filesystem() - it's a final cleanup */
-
-void kern_umount(struct vfsmount *mnt)
-{
- struct super_block *sb = mnt->mnt_sb;
- spin_lock(&dcache_lock);
- remove_vfsmnt(mnt);
- kill_super(sb);
-}
-
/*
* Doesn't take quota and stuff into account. IOW, in some cases it will
* give false negatives. The main reason why it's here is that we need
static int do_umount(struct vfsmount *mnt, int flags)
{
struct super_block * sb = mnt->mnt_sb;
+ struct nameidata parent_nd;
/*
* No sense to grab the lock for this test, but test itself looks
* Special case for "unmounting" root ...
* we just try to remount it readonly.
*/
- mntput(mnt);
return do_remount("/", MS_RDONLY, NULL);
}
if (mnt->mnt_instances.next != mnt->mnt_instances.prev) {
if (atomic_read(&mnt->mnt_count) > 2) {
spin_unlock(&dcache_lock);
- mntput(mnt);
return -EBUSY;
}
if (sb->s_type->fs_flags & FS_SINGLE)
put_filesystem(sb->s_type);
- /* We hold two references, so mntput() is safe */
+ detach_mnt(mnt, &parent_nd);
+ list_del(&mnt->mnt_list);
+ spin_unlock(&dcache_lock);
mntput(mnt);
- remove_vfsmnt(mnt);
+ if (parent_nd.mnt != mnt)
+ path_release(&parent_nd);
return 0;
}
spin_unlock(&dcache_lock);
spin_lock(&dcache_lock);
if (atomic_read(&mnt->mnt_count) > 2) {
spin_unlock(&dcache_lock);
- mntput(mnt);
return -EBUSY;
}
/* OK, that's the point of no return */
+ detach_mnt(mnt, &parent_nd);
+ list_del(&mnt->mnt_list);
+ spin_unlock(&dcache_lock);
mntput(mnt);
- remove_vfsmnt(mnt);
-
- kill_super(sb);
+ if (parent_nd.mnt != mnt)
+ path_release(&parent_nd);
return 0;
}
char *kname;
int retval;
- lock_kernel();
kname = getname(name);
retval = PTR_ERR(kname);
if (IS_ERR(kname))
if (!capable(CAP_SYS_ADMIN) && current->uid!=nd.mnt->mnt_owner)
goto dput_and_out;
- dput(nd.dentry);
- /* puts nd.mnt */
down(&mount_sem);
+ lock_kernel();
retval = do_umount(nd.mnt, flags);
+ unlock_kernel();
+ path_release(&nd);
up(&mount_sem);
goto out;
dput_and_out:
path_release(&nd);
out:
- unlock_kernel();
return retval;
}
fail:
if (fstype->fs_flags & FS_SINGLE)
put_filesystem(fstype);
- if (list_empty(&sb->s_mounts))
- kill_super(sb);
+ kill_super(sb);
goto unlock_out;
}
* - we don't move root/cwd if they are not at the root (reason: if something
* cared enough to change them, it's probably wrong to force them elsewhere)
* - it's okay to pick a root that isn't the root of a file system, e.g.
- * /nfs/my_root where /nfs is the mount point. Better avoid creating
- * unreachable mount points this way, though.
+ * /nfs/my_root where /nfs is the mount point. It must be a mountpoint,
+ * though, so you may need to say mount --bind /nfs/my_root /nfs/my_root
+ * first.
*/
asmlinkage long sys_pivot_root(const char *new_root, const char *put_old)
struct dentry *root;
struct vfsmount *root_mnt;
struct vfsmount *tmp;
- struct nameidata new_nd, old_nd;
+ struct nameidata new_nd, old_nd, parent_nd, root_parent;
char *name;
int error;
if (new_nd.mnt == root_mnt || old_nd.mnt == root_mnt)
goto out2; /* loop */
error = -EINVAL;
+ if (root_mnt->mnt_root != root)
+ goto out2;
+ if (new_nd.mnt->mnt_root != new_nd.dentry)
+ goto out2; /* not a mountpoint */
tmp = old_nd.mnt; /* make sure we can reach put_old from new_root */
spin_lock(&dcache_lock);
if (tmp != new_nd.mnt) {
goto out3;
} else if (!is_subdir(old_nd.dentry, new_nd.dentry))
goto out3;
+ detach_mnt(new_nd.mnt, &parent_nd);
+ detach_mnt(root_mnt, &root_parent);
+ attach_mnt(root_mnt, &old_nd);
+ if (root_parent.mnt != root_mnt)
+ attach_mnt(new_nd.mnt, &root_parent);
spin_unlock(&dcache_lock);
-
- move_vfsmnt(new_nd.mnt, new_nd.dentry, NULL, NULL);
- move_vfsmnt(root_mnt, old_nd.dentry, old_nd.mnt, NULL);
chroot_fs_refs(root,root_mnt,new_nd.dentry,new_nd.mnt);
error = 0;
+ if (root_parent.mnt != root_mnt)
+ path_release(&root_parent);
+ if (parent_nd.mnt != new_nd.mnt)
+ path_release(&parent_nd);
out2:
up(&old_nd.dentry->d_inode->i_zombie);
up(&mount_sem);
if (!error) {
if (devfs_nd.mnt->mnt_sb->s_magic == DEVFS_SUPER_MAGIC &&
devfs_nd.dentry == devfs_nd.mnt->mnt_root) {
- dput(devfs_nd.dentry);
down(&mount_sem);
- /* puts devfs_nd.mnt */
do_umount(devfs_nd.mnt, 0);
+ path_release(&devfs_nd);
up(&mount_sem);
} else
path_release(&devfs_nd);
printk(KERN_NOTICE "Trying to unmount old root ... ");
if (!blivet) {
blivet = do_umount(old_rootmnt, 0);
+ mntput(old_rootmnt);
if (!blivet) {
ioctl_by_bdev(ramdisk, BLKFLSBUF, 0);
printk("okay\n");
return error;
}
/* FIXME: we should hold i_zombie on nd.dentry */
- move_vfsmnt(old_rootmnt, nd.dentry, nd.mnt, "/dev/root.old");
+ move_vfsmnt(old_rootmnt, &nd, "/dev/root.old");
mntput(old_rootmnt);
path_release(&nd);
return 0;
{
int *m = ((int *) addr) + (nr >> 5);
- *m |= 1UL << (nr & 31);
+ *m |= 1 << (nr & 31);
}
#define smp_mb__before_clear_bit() smp_mb()
:"Ir" (~(1UL << (nr & 31))), "m" (*m));
}
+/*
+ * WARNING: non atomic version.
+ */
+static __inline__ void
+__change_bit(unsigned long nr, volatile void * addr)
+{
+ int *m = ((int *) addr) + (nr >> 5);
+
+ *m ^= 1 << (nr & 31);
+}
+
extern __inline__ void
change_bit(unsigned long nr, volatile void * addr)
{
return (old & mask) != 0;
}
+/*
+ * WARNING: non atomic version.
+ */
+static __inline__ int
+__test_and_change_bit(unsigned long nr, volatile void * addr)
+{
+ unsigned long mask = 1 << (nr & 0x1f);
+ int *m = ((int *) addr) + (nr >> 5);
+ int old = *m;
+
+ *m = old ^ mask;
+ return (old & mask) != 0;
+}
+
extern __inline__ int
test_and_change_bit(unsigned long nr, volatile void * addr)
{
/* The IO address space is larger than 0xffff */
#define TSUNAMI_IO_SPACE (TSUNAMI_CONF(0) - TSUNAMI_IO(0))
+/* Offset between ram physical addresses and pci64 DAC bus addresses */
+#define TSUNAMI_DAC_OFFSET (1UL << 40)
+
/*
* Data structure for handling TSUNAMI machine checks:
*/
--- /dev/null
+/*
+ * Written by Kanoj Sarcar (kanoj@sgi.com) Aug 99
+ * Adapted for the alpha wildfire architecture Jan 2001.
+ */
+#ifndef _ASM_MMZONE_H_
+#define _ASM_MMZONE_H_
+
+#include <linux/config.h>
+#ifdef CONFIG_NUMA_SCHED
+#include <linux/numa_sched.h>
+#endif
+#ifdef NOTYET
+#include <asm/sn/types.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/klkernvars.h>
+#endif /* NOTYET */
+
+typedef struct plat_pglist_data {
+ pg_data_t gendata;
+#ifdef NOTYET
+ kern_vars_t kern_vars;
+#endif
+#if defined(CONFIG_NUMA) && defined(CONFIG_NUMA_SCHED)
+ struct numa_schedule_data schedule_data;
+#endif
+} plat_pg_data_t;
+
+struct bootmem_data_t; /* stupid forward decl. */
+
+/*
+ * Following are macros that are specific to this numa platform.
+ */
+
+extern plat_pg_data_t *plat_node_data[];
+
+#ifdef CONFIG_ALPHA_WILDFIRE
+# define ALPHA_PA_TO_NID(pa) ((pa) >> 36) /* 16 nodes max due 43bit kseg */
+#define NODE_MAX_MEM_SIZE (64L * 1024L * 1024L * 1024L) /* 64 GB */
+#define MAX_NUMNODES WILDFIRE_MAX_QBB
+#else
+# define ALPHA_PA_TO_NID(pa) (0)
+#define NODE_MAX_MEM_SIZE (~0UL)
+#define MAX_NUMNODES 1
+#endif
+
+#define PHYSADDR_TO_NID(pa) ALPHA_PA_TO_NID(pa)
+#define PLAT_NODE_DATA(n) (plat_node_data[(n)])
+#define PLAT_NODE_DATA_STARTNR(n) \
+ (PLAT_NODE_DATA(n)->gendata.node_start_mapnr)
+#define PLAT_NODE_DATA_SIZE(n) (PLAT_NODE_DATA(n)->gendata.node_size)
+
+#if 1
+#define PLAT_NODE_DATA_LOCALNR(p, n) \
+ (((p) - PLAT_NODE_DATA(n)->gendata.node_start_paddr) >> PAGE_SHIFT)
+#else
+static inline unsigned long
+PLAT_NODE_DATA_LOCALNR(unsigned long p, int n)
+{
+ unsigned long temp;
+ temp = p - PLAT_NODE_DATA(n)->gendata.node_start_paddr;
+ return (temp >> PAGE_SHIFT);
+}
+#endif
+
+#ifdef CONFIG_DISCONTIGMEM
+
+/*
+ * Following are macros that each numa implmentation must define.
+ */
+
+/*
+ * Given a kernel address, find the home node of the underlying memory.
+ */
+#define KVADDR_TO_NID(kaddr) PHYSADDR_TO_NID(__pa(kaddr))
+
+/*
+ * Return a pointer to the node data for node n.
+ */
+#define NODE_DATA(n) (&((PLAT_NODE_DATA(n))->gendata))
+
+/*
+ * NODE_MEM_MAP gives the kaddr for the mem_map of the node.
+ */
+#define NODE_MEM_MAP(nid) (NODE_DATA(nid)->node_mem_map)
+
+/*
+ * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
+ * and returns the the mem_map of that node.
+ */
+#define ADDR_TO_MAPBASE(kaddr) \
+ NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(kaddr)))
+
+/*
+ * Given a kaddr, LOCAL_BASE_ADDR finds the owning node of the memory
+ * and returns the kaddr corresponding to first physical page in the
+ * node's mem_map.
+ */
+#define LOCAL_BASE_ADDR(kaddr) ((unsigned long)__va(NODE_DATA(KVADDR_TO_NID(kaddr))->node_start_paddr))
+
+#define LOCAL_MAP_NR(kvaddr) \
+ (((unsigned long)(kvaddr)-LOCAL_BASE_ADDR(kvaddr)) >> PAGE_SHIFT)
+
+#define kern_addr_valid(kaddr) test_bit(LOCAL_MAP_NR(kaddr), \
+ NODE_DATA(KVADDR_TO_NID(kaddr))->valid_addr_bitmap)
+
+#define virt_to_page(kaddr) (ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr))
+#define VALID_PAGE(page) (((page) - mem_map) < max_mapnr)
+
+#ifdef CONFIG_NUMA
+#ifdef CONFIG_NUMA_SCHED
+#define NODE_SCHEDULE_DATA(nid) (&((PLAT_NODE_DATA(nid))->schedule_data))
+#endif
+
+#ifdef CONFIG_ALPHA_WILDFIRE
+/* With wildfire assume 4 CPUs per node */
+#define cputonode(cpu) ((cpu) >> 2)
+#else
+#define cputonode(cpu) 0
+#endif /* CONFIG_ALPHA_WILDFIRE */
+
+#define numa_node_id() cputonode(smp_processor_id())
+#endif /* CONFIG_NUMA */
+
+#endif /* CONFIG_DISCONTIGMEM */
+
+#endif /* _ASM_MMZONE_H_ */
#ifndef _ALPHA_PAGE_H
#define _ALPHA_PAGE_H
+#include <asm/pal.h>
+
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT 13
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define pgprot_val(x) ((x).pgprot)
#define __pte(x) ((pte_t) { (x) } )
+#define __pmd(x) ((pmd_t) { (x) } )
#define __pgd(x) ((pgd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } )
#endif /* STRICT_MM_TYPECHECKS */
-#define BUG() __asm__ __volatile__("call_pal 129 # bugchk")
+#define BUG() \
+do { \
+ printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+ __asm__ __volatile__("call_pal %0 # bugchk" : : "i" (PAL_bugchk)); \
+} while (0)
#define PAGE_BUG(page) BUG()
/* Pure 2^n version of get_order */
#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET)
#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET))
+#ifndef CONFIG_DISCONTIGMEM
#define virt_to_page(kaddr) (mem_map + (__pa(kaddr) >> PAGE_SHIFT))
-#define VALID_PAGE(page) ((page - mem_map) < max_mapnr)
+#define VALID_PAGE(page) (((page) - mem_map) < max_mapnr)
+#endif /* CONFIG_DISCONTIGMEM */
#endif /* __KERNEL__ */
#ifndef CONFIG_SMP
extern struct pgtable_cache_struct {
unsigned long *pgd_cache;
+ unsigned long *pmd_cache;
unsigned long *pte_cache;
unsigned long pgtable_cache_sz;
} quicklists;
#define quicklists cpu_data[smp_processor_id()]
#endif
#define pgd_quicklist (quicklists.pgd_cache)
-#define pmd_quicklist ((unsigned long *)0)
+#define pmd_quicklist (quicklists.pmd_cache)
#define pte_quicklist (quicklists.pte_cache)
#define pgtable_cache_size (quicklists.pgtable_cache_sz)
if ((ret = pgd_quicklist) != NULL) {
pgd_quicklist = (unsigned long *)(*ret);
- ret[0] = ret[1];
+ ret[0] = 0;
pgtable_cache_size--;
} else
ret = (unsigned long *)get_pgd_slow();
if ((ret = (unsigned long *)pte_quicklist) != NULL) {
pte_quicklist = (unsigned long *)(*ret);
- ret[0] = ret[1];
+ ret[0] = 0;
pgtable_cache_size--;
}
return (pmd_t *)ret;
if ((ret = (unsigned long *)pte_quicklist) != NULL) {
pte_quicklist = (unsigned long *)(*ret);
- ret[0] = ret[1];
+ ret[0] = 0;
pgtable_cache_size--;
}
return (pte_t *)ret;
* in <asm/page.h> (currently 8192).
*/
#include <linux/config.h>
+#include <linux/mmzone.h>
#include <asm/page.h>
#include <asm/processor.h> /* For TASK_SIZE */
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
*/
+#ifndef CONFIG_DISCONTIGMEM
+#define PAGE_TO_PA(page) ((page - mem_map) << PAGE_SHIFT)
+#else
+#define PAGE_TO_PA(page) \
+ ((((page)-(page)->zone->zone_mem_map) << PAGE_SHIFT) \
+ + (page)->zone->zone_start_paddr)
+#endif
+
+#ifndef CONFIG_DISCONTIGMEM
#define mk_pte(page, pgprot) \
({ \
pte_t pte; \
pgprot_val(pgprot); \
pte; \
})
+#else
+#define mk_pte(page, pgprot) \
+({ \
+ pte_t pte; \
+ unsigned long pfn; \
+ \
+ pfn = ((unsigned long)((page)-(page)->zone->zone_mem_map)) << 32; \
+ pfn += (page)->zone->zone_start_paddr << (32-PAGE_SHIFT); \
+ pte_val(pte) = pfn | pgprot_val(pgprot); \
+ \
+ pte; \
+})
+#endif
extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
{ pte_t pte; pte_val(pte) = (PHYS_TWIDDLE(physpage) << (32-PAGE_SHIFT)) | pgprot_val(pgprot); return pte; }
extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
{ pgd_val(*pgdp) = _PAGE_TABLE | ((((unsigned long) pmdp) - PAGE_OFFSET) << (32-PAGE_SHIFT)); }
+#ifndef CONFIG_DISCONTIGMEM
#define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> 32)))
+#else
+#define pte_page(x) \
+({ \
+ unsigned long kvirt; \
+ struct page * __xx; \
+ \
+ kvirt = (unsigned long)__va(pte_val(x) >> (32-PAGE_SHIFT)); \
+ __xx = virt_to_page(kvirt); \
+ \
+ __xx; \
+})
+#endif
extern inline unsigned long pmd_page(pmd_t pmd)
{ return PAGE_OFFSET + ((pmd_val(pmd) & _PFN_MASK) >> (32-PAGE_SHIFT)); }
/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
#define PageSkip(page) (0)
+
+#ifndef CONFIG_DISCONTIGMEM
#define kern_addr_valid(addr) (1)
+#endif
#define io_remap_page_range(start, busaddr, size, prot) \
remap_page_range(start, virt_to_phys(__ioremap(busaddr)), size, prot)
int need_new_asn;
int asn_lock;
unsigned long *pgd_cache;
+ unsigned long *pmd_cache;
unsigned long *pte_cache;
unsigned long pgtable_cache_sz;
unsigned long ipi_count;
#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
+#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
+
#if DEBUG_RWLOCK
extern void write_lock(rwlock_t * lock);
extern void read_lock(rwlock_t * lock);
#define START_ADDR (PAGE_OFFSET+KERNEL_START_PHYS+0x10000)
+/*
+ * This is setup by the secondary bootstrap loader. Because
+ * the zero page is zeroed out as soon as the vm system is
+ * initialized, we need to copy things out into a more permanent
+ * place.
+ */
+#define PARAM ZERO_PGE
+#define COMMAND_LINE ((char*)(PARAM + 0x0000))
+#define COMMAND_LINE_SIZE 256
+#define INITRD_START (*(unsigned long *) (PARAM+0x100))
+#define INITRD_SIZE (*(unsigned long *) (PARAM+0x108))
+
#ifndef __ASSEMBLY__
#include <linux/kernel.h>
#define smp_mb__before_clear_bit() barrier()
#define smp_mb__after_clear_bit() barrier()
+/**
+ * __change_bit - Toggle a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * Unlike change_bit(), this function is non-atomic and may be reordered.
+ * If it's called on the same region of memory simultaneously, the effect
+ * may be that only one operation succeeds.
+ */
+static __inline__ void __change_bit(int nr, volatile void * addr)
+{
+ __asm__ __volatile__(
+ "btcl %1,%0"
+ :"=m" (ADDR)
+ :"Ir" (nr));
+}
+
/**
* change_bit - Toggle a bit in memory
* @nr: Bit to clear
return oldbit;
}
+/* WARNING: non atomic and it can be reordered! */
+static __inline__ int __test_and_change_bit(int nr, volatile void * addr)
+{
+ int oldbit;
+
+ __asm__ __volatile__(
+ "btcl %2,%1\n\tsbbl %0,%0"
+ :"=r" (oldbit),"=m" (ADDR)
+ :"Ir" (nr) : "memory");
+ return oldbit;
+}
+
/**
* test_and_change_bit - Change a bit and return its new value
* @nr: Bit to set
/*
- * BK Id: SCCS/s.bootinfo.h 1.5 05/17/01 18:14:24 cort
+ * BK Id: SCCS/s.bootinfo.h 1.7 05/23/01 00:38:42 cort
*/
/*
* Non-machine dependent bootinfo structure. Basic idea
* Copyright (C) 1999 Cort Dougan <cort@ppc.kernel.org>
*/
-
#ifdef __KERNEL__
#ifndef _PPC_BOOTINFO_H
#define _PPC_BOOTINFO_H
#endif /* CONFIG_APUS */
-#endif /* _PPC_BOOTINFO_H */
+/*
+ * prom_init() is called very early on, before the kernel text
+ * and data have been mapped to KERNELBASE. At this point the code
+ * is running at whatever address it has been loaded at, so
+ * references to extern and static variables must be relocated
+ * explicitly. The procedure reloc_offset() returns the address
+ * we're currently running at minus the address we were linked at.
+ * (Note that strings count as static variables.)
+ *
+ * Because OF may have mapped I/O devices into the area starting at
+ * KERNELBASE, particularly on CHRP machines, we can't safely call
+ * OF once the kernel has been mapped to KERNELBASE. Therefore all
+ * OF calls should be done within prom_init(), and prom_init()
+ * and all routines called within it must be careful to relocate
+ * references as necessary.
+ */
+#define PTRRELOC(x) ((typeof(x))((unsigned long)(x) + offset))
+#define PTRUNRELOC(x) ((typeof(x))((unsigned long)(x) - offset))
+#define RELOC(x) (*PTRRELOC(&(x)))
+#endif /* _PPC_BOOTINFO_H */
#endif /* __KERNEL__ */
+
+
#define SR15 15
#ifndef __ASSEMBLY__
-#ifndef CONFIG_MACH_SPECIFIC
+#if defined(CONFIG_ALL_PPC)
extern int _machine;
extern int have_of;
-#endif /* CONFIG_MACH_SPECIFIC */
+#endif /* CONFIG_ALL_PPC */
/* what kind of prep workstation we are */
extern int _prep_type;
#endif /* ndef ASSEMBLY*/
-#ifdef CONFIG_MACH_SPECIFIC
-#if defined(CONFIG_8xx)
-#define _machine _MACH_8xx
-#define have_of 0
+#ifndef CONFIG_ALL_PPC
+#if defined(CONFIG_APUS)
+#define _machine _MACH_apus
+#elif defined(CONFIG_GEMINI)
+#define _machine _MACH_gemini
#elif defined(CONFIG_OAK)
#define _machine _MACH_oak
-#define have_of 0
#elif defined(CONFIG_WALNUT)
#define _machine _MACH_walnut
-#define have_of 0
-#elif defined(CONFIG_APUS)
-#define _machine _MACH_apus
-#define have_of 0
-#elif defined(CONFIG_GEMINI)
-#define _machine _MACH_gemini
-#define have_of 0
+#elif defined(CONFIG_8xx)
+#define _machine _MACH_8xx
#elif defined(CONFIG_8260)
#define _machine _MACH_8260
-#define have_of 0
#else
#error "Machine not defined correctly"
#endif
-#endif /* CONFIG_MACH_SPECIFIC */
+#define have_of 0
+#endif /* !CONFIG_ALL_PPC */
#endif /* __ASM_PPC_PROCESSOR_H */
#endif /* __KERNEL__ */
extern int register_filesystem(struct file_system_type *);
extern int unregister_filesystem(struct file_system_type *);
extern struct vfsmount *kern_mount(struct file_system_type *);
-extern void kern_umount(struct vfsmount *);
extern int may_umount(struct vfsmount *);
extern long do_mount(char *, char *, char *, unsigned long, void *);
+#define kern_umount mntput
extern int vfs_statfs(struct super_block *, struct statfs *);
#else
#define __GFP_HIGHMEM 0x0 /* noop */
#endif
-#define __GFP_VM 0x20
#define GFP_BUFFER (__GFP_HIGH | __GFP_WAIT)
typedef struct free_area_struct {
struct list_head free_list;
- unsigned int *map;
+ unsigned long *map;
} free_area_t;
struct pglist_data;
* Commonly accessed fields:
*/
spinlock_t lock;
- unsigned long offset;
unsigned long free_pages;
unsigned long inactive_clean_pages;
unsigned long inactive_dirty_pages;
struct list_head inactive_clean_list;
free_area_t free_area[MAX_ORDER];
- /*
- * rarely used fields:
- */
- char *name;
- unsigned long size;
/*
* Discontig memory support fields.
*/
struct pglist_data *zone_pgdat;
+ struct page *zone_mem_map;
unsigned long zone_start_paddr;
unsigned long zone_start_mapnr;
- struct page *zone_mem_map;
+
+ /*
+ * rarely used fields:
+ */
+ char *name;
+ unsigned long size;
} zone_t;
#define ZONE_DMA 0
int gfp_mask;
} zonelist_t;
-#define NR_GFPINDEX 0x100
+#define NR_GFPINDEX 0x20
/*
* The pg_data_t structure is used in machines with CONFIG_DISCONTIGMEM
extern pg_data_t *pgdat_list;
#define memclass(pgzone, tzone) (((pgzone)->zone_pgdat == (tzone)->zone_pgdat) \
- && (((pgzone) - (pgzone)->zone_pgdat->node_zones) <= \
- ((tzone) - (pgzone)->zone_pgdat->node_zones)))
+ && ((pgzone) <= (tzone)))
/*
* The following two are not meant for general usage. They are here as
return mnt;
}
+extern void __mntput(struct vfsmount *mnt);
+
static inline void mntput(struct vfsmount *mnt)
{
if (mnt) {
if (atomic_dec_and_test(&mnt->mnt_count))
- BUG();
+ __mntput(mnt);
}
}
#define EOF_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? EOF_FAT32 : \
MSDOS_SB(s)->fat_bits == 16 ? EOF_FAT16 : EOF_FAT12)
+#define FAT_FSINFO_SIG1 0x41615252
+#define FAT_FSINFO_SIG2 0x61417272
+#define IS_FSINFO(x) (CF_LE_L((x)->signature1) == FAT_FSINFO_SIG1 \
+ && CF_LE_L((x)->signature2) == FAT_FSINFO_SIG2)
+
/*
* Inode flags
*/
};
struct fat_boot_fsinfo {
- __u32 reserved1; /* Nothing as far as I can tell */
- __u32 signature; /* 0x61417272L */
+ __u32 signature1; /* 0x61417272L */
+ __u32 reserved1[120]; /* Nothing as far as I can tell */
+ __u32 signature2; /* 0x61417272L */
__u32 free_clusters; /* Free cluster count. -1 if unknown */
__u32 next_cluster; /* Most recently allocated cluster.
* Unused under Linux. */
{
/* Fast stuff first */
if (*bh && *de &&
- (*de - (struct msdos_dir_entry *)(*bh)->b_data) < MSDOS_DPB-1) {
+ (*de - (struct msdos_dir_entry *)(*bh)->b_data) < MSDOS_SB(dir->i_sb)->dir_per_block - 1) {
*pos += sizeof(struct msdos_dir_entry);
(*de)++;
(*ino)++;
unsigned long data_start; /* first data sector */
unsigned long clusters; /* number of clusters */
unsigned long root_cluster; /* first cluster of the root directory */
- unsigned long fsinfo_offset; /* FAT32 fsinfo offset from start of disk */
+ unsigned long fsinfo_sector; /* FAT32 fsinfo offset from start of disk */
wait_queue_head_t fat_wait;
struct semaphore fat_lock;
int prev_free; /* previously returned free cluster number */
struct nls_table *nls_io; /* Charset used for input and display */
struct cvf_format* cvf_format;
void *dir_ops; /* Opaque; default directory operations */
- void *private_data;
+ void *private_data;
+ int dir_per_block; /* dir entries per block */
+ int dir_per_block_bits; /* log2(dir_per_block) */
};
#endif
};
extern int nr_swap_pages;
-FASTCALL(unsigned int nr_free_pages(void));
-FASTCALL(unsigned int nr_inactive_clean_pages(void));
-FASTCALL(unsigned int nr_free_buffer_pages(void));
+extern unsigned int nr_free_pages(void);
+extern unsigned int nr_inactive_clean_pages(void);
+extern unsigned int nr_free_buffer_pages(void);
extern int nr_active_pages;
extern int nr_inactive_dirty_pages;
extern atomic_t nr_async_pages;
#define SPPPIOCCISCO (SIOCDEVPRIVATE)
#define SPPPIOCPPP (SIOCDEVPRIVATE+1)
#define SPPPIOCDEBUG (SIOCDEVPRIVATE+2)
+#define SPPPIOCSFLAGS (SIOCDEVPRIVATE+3)
+#define SPPPIOCGFLAGS (SIOCDEVPRIVATE+4)
#endif /* _SYNCPPP_H_ */
EXPORT_SYMBOL(free_pages);
#ifndef CONFIG_DISCONTIGMEM
EXPORT_SYMBOL(contig_page_data);
+#else
+EXPORT_SYMBOL(alloc_pages);
#endif
EXPORT_SYMBOL(num_physpages);
EXPORT_SYMBOL(kmem_find_general_cachep);
EXPORT_SYMBOL(register_filesystem);
EXPORT_SYMBOL(unregister_filesystem);
EXPORT_SYMBOL(kern_mount);
-EXPORT_SYMBOL(kern_umount);
+EXPORT_SYMBOL(__mntput);
EXPORT_SYMBOL(may_umount);
/* executable format registration */
if (!size) BUG();
+ if (sidx < 0)
+ BUG();
+ if (eidx < 0)
+ BUG();
+ if (sidx >= eidx)
+ BUG();
+ if ((addr >> PAGE_SHIFT) >= bdata->node_low_pfn)
+ BUG();
if (end > bdata->node_low_pfn)
BUG();
for (i = sidx; i < eidx; i++)
if (!size) BUG();
+ if (align & (align-1))
+ BUG();
+
/*
* We try to allocate bootmem pages above 'goal'
* first, then we try to allocate lower pages.
* of num_physpages for safety margin.
*/
- long free;
+ unsigned long free;
/* Sometimes we want to use more memory than we have. */
if (sysctl_overcommit_memory)
/*
* Temporary debugging check.
*/
-#define BAD_RANGE(zone,x) (((zone) != (x)->zone) || (((x)-mem_map) < (zone)->offset) || (((x)-mem_map) >= (zone)->offset+(zone)->size))
+#define BAD_RANGE(zone,x) (((zone) != (x)->zone) || (((x)-mem_map) < (zone)->zone_start_mapnr) || (((x)-mem_map) >= (zone)->zone_start_mapnr+(zone)->size))
/*
* Buddy system. Hairy. You really aren't expected to understand this
zone = page->zone;
mask = (~0UL) << order;
- base = mem_map + zone->offset;
+ base = zone->zone_mem_map;
page_idx = page - base;
if (page_idx & ~mask)
BUG();
if (area >= zone->free_area + MAX_ORDER)
BUG();
- if (!test_and_change_bit(index, area->map))
+ if (!__test_and_change_bit(index, area->map))
/*
* the buddy page is still allocated.
*/
}
#define MARK_USED(index, order, area) \
- change_bit((index) >> (1+(order)), (area)->map)
+ __change_bit((index) >> (1+(order)), (area)->map)
static inline struct page * expand (zone_t *zone, struct page *page,
unsigned long index, int low, int high, free_area_t * area)
if (BAD_RANGE(zone,page))
BUG();
memlist_del(curr);
- index = (page - mem_map) - zone->offset;
- MARK_USED(index, curr_order, area);
+ index = page - zone->zone_mem_map;
+ if (curr_order != MAX_ORDER-1)
+ MARK_USED(index, curr_order, area);
zone->free_pages -= 1 << order;
page = expand(zone, page, index, order, curr_order, area);
unsigned long i, j;
unsigned long map_size;
unsigned long totalpages, offset, realtotalpages;
- unsigned int cumulative = 0;
+ const unsigned long zone_required_alignment = 1UL << (MAX_ORDER-1);
+
+ if (zone_start_paddr & ~PAGE_MASK)
+ BUG();
totalpages = 0;
for (i = 0; i < MAX_NR_ZONES; i++) {
if (!size)
continue;
- zone->offset = offset;
- cumulative += size;
mask = (realsize / zone_balance_ratio[j]);
if (mask < zone_balance_min[j])
mask = zone_balance_min[j];
zone->zone_start_mapnr = offset;
zone->zone_start_paddr = zone_start_paddr;
+ if ((zone_start_paddr >> PAGE_SHIFT) & (zone_required_alignment-1))
+ printk("BUG: wrong zone alignment, it will crash\n");
+
for (i = 0; i < size; i++) {
struct page *page = mem_map + offset + i;
page->zone = zone;
- if (j != ZONE_HIGHMEM) {
+ if (j != ZONE_HIGHMEM)
page->virtual = __va(zone_start_paddr);
- zone_start_paddr += PAGE_SIZE;
- }
+ zone_start_paddr += PAGE_SIZE;
}
offset += size;
mask = -1;
- for (i = 0; i < MAX_ORDER; i++) {
+ for (i = 0; ; i++) {
unsigned long bitmap_size;
memlist_init(&zone->free_area[i].free_list);
+ if (i == MAX_ORDER-1) {
+ zone->free_area[i].map = NULL;
+ break;
+ }
mask += mask;
size = (size + ~mask) & mask;
- bitmap_size = size >> i;
+ bitmap_size = size >> (i+1);
bitmap_size = (bitmap_size + 7) >> 3;
bitmap_size = LONG_ALIGN(bitmap_size);
zone->free_area[i].map =
- (unsigned int *) alloc_bootmem_node(pgdat, bitmap_size);
+ (unsigned long *) alloc_bootmem_node(pgdat, bitmap_size);
}
}
build_zonelists(pgdat);
struct page * read_swap_cache_async(swp_entry_t entry)
{
struct page *found_page = 0, *new_page;
- unsigned long new_page_addr;
/*
* Make sure the swap entry is still in use.
if (found_page)
goto out_free_swap;
- new_page_addr = __get_free_page(GFP_USER);
- if (!new_page_addr)
+ new_page = alloc_page(GFP_USER);
+ if (!new_page)
goto out_free_swap; /* Out of memory */
- new_page = virt_to_page(new_page_addr);
/*
* Check the swap cache again, in case we stalled above.
/*
* Add it to the swap cache and read its contents.
*/
- lock_page(new_page);
+ if (TryLockPage(new_page))
+ BUG();
add_to_swap_cache(new_page, entry);
rw_swap_page(READ, new_page);
return new_page;
for (p = &vmlist; (tmp = *p) ; p = &tmp->next) {
if ((size + addr) < addr)
goto out;
- if (size + addr < (unsigned long) tmp->addr)
+ if (size + addr <= (unsigned long) tmp->addr)
break;
addr = tmp->size + (unsigned long) tmp->addr;
if (addr > VMALLOC_END-size)
{
struct task_struct *tsk = current;
- tsk->session = 1;
- tsk->pgrp = 1;
+ daemonize();
strcpy(tsk->comm, "kswapd");
sigfillset(&tsk->blocked);
struct task_struct *tsk = current;
pg_data_t *pgdat;
- tsk->session = 1;
- tsk->pgrp = 1;
+ daemonize();
strcpy(tsk->comm, "kreclaimd");
sigfillset(&tsk->blocked);
current->flags |= PF_MEMALLOC;
/*
* Linux NET3: IP/IP protocol decoder.
*
- * Version: $Id: ipip.c,v 1.45 2001/04/19 22:32:55 davem Exp $
+ * Version: $Id: ipip.c,v 1.46 2001/05/17 04:12:18 davem Exp $
*
* Authors:
* Sam Lantinga (slouken@cs.ucdavis.edu) 02/01/95
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp_input.c,v 1.229 2001/05/13 18:14:46 davem Exp $
+ * Version: $Id: tcp_input.c,v 1.231 2001/05/22 05:15:16 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
queued = tcp_rcv_synsent_state_process(sk, skb, th, len);
if (queued >= 0)
return queued;
- queued = 0;
- goto step6;
+
+ /* Do step6 onward by hand. */
+ tcp_urg(sk, skb, th);
+ __kfree_skb(skb);
+ tcp_data_snd_check(sk);
+ return 0;
}
if (tcp_fast_parse_options(skb, th, tp) && tp->saw_tstamp &&
} else
goto discard;
-step6:
/* step 6: check the URG bit */
tcp_urg(sk, skb, th);
* Pedro Roque <roque@di.fc.ul.pt>
* Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
*
- * $Id: sit.c,v 1.50 2001/04/19 22:32:55 davem Exp $
+ * $Id: sit.c,v 1.51 2001/05/17 04:12:18 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
offs = file->f_pos;
if (offs < pos) {
len = min(pos - offs, count);
- if(copy_to_user(buf, (page + offs), len))
+ if (copy_to_user(buf, (page + offs), len)) {
+ kfree(page);
return -EFAULT;
+ }
file->f_pos += len;
}
else