Next in my series of cleanups form the alpha port nothing should break yet...
This commit is contained in:
parent
55366fa657
commit
24fe8d03aa
28 changed files with 1672 additions and 143 deletions
109
src/arch/i386/config/crt0.base
Normal file
109
src/arch/i386/config/crt0.base
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* $ $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <asm.h>
|
||||
#include <intel.h>
|
||||
|
||||
#include <pciconf.h>
|
||||
/*
|
||||
* This is the entry code (the mkrom(8) utility makes a jumpvector
|
||||
* to this adddess.
|
||||
*
|
||||
* When we get here we are in x86 real mode.
|
||||
*
|
||||
* %cs = 0xf000 %ip = 0x0000
|
||||
* %ds = 0x0000 %es = 0x0000
|
||||
* %dx = 0x0yxx (y = 3 for i386, 5 for pentium, 6 for P6,
|
||||
* where x is undefined)
|
||||
* %fl = 0x0002
|
||||
*/
|
||||
.text
|
||||
.code16
|
||||
|
||||
#include <cpu/p5/start32.inc>
|
||||
|
||||
#include <pc80/i8259.inc>
|
||||
|
||||
CRT0_PARAMETERS
|
||||
|
||||
/* Turn on mtrr for faster boot */
|
||||
#include <cpu/p6/earlymtrr.inc>
|
||||
|
||||
/*
|
||||
* Copy data into RAM and clear the BSS. Since these segments
|
||||
* isn\'t really that big we just copy/clear using bytes, not
|
||||
* double words.
|
||||
*/
|
||||
intel_chip_post_macro(0x11) /* post 11 */
|
||||
|
||||
#ifdef SERIAL_CONSOLE
|
||||
TTYS0_TX_STRING($str_after_ram)
|
||||
#endif /* SERIAL_CONSOLE */
|
||||
|
||||
cld /* clear direction flag */
|
||||
|
||||
/* copy data segment from FLASH ROM to RAM */
|
||||
leal EXT(_ldata), %esi
|
||||
leal EXT(_data), %edi
|
||||
movl $EXT(_eldata), %ecx
|
||||
subl %esi, %ecx
|
||||
jz .Lnodata /* should not happen */
|
||||
rep
|
||||
movsb
|
||||
.Lnodata:
|
||||
intel_chip_post_macro(0x12) /* post 12 */
|
||||
|
||||
#ifdef SERIAL_CONSOLE
|
||||
TTYS0_TX_STRING($str_after_ram)
|
||||
#endif /* SERIAL_CONSOLE */
|
||||
|
||||
/** clear stack */
|
||||
leal EXT(_stack), %edi
|
||||
movl $EXT(_estack), %ecx
|
||||
subl %edi, %ecx
|
||||
xorl %eax, %eax
|
||||
rep
|
||||
stosb
|
||||
|
||||
/** clear bss */
|
||||
leal EXT(_bss), %edi
|
||||
movl $EXT(_ebss), %ecx
|
||||
subl %edi, %ecx
|
||||
jz .Lnobss
|
||||
xorl %eax, %eax
|
||||
rep
|
||||
stosb
|
||||
.Lnobss:
|
||||
|
||||
/*
|
||||
* Now we are finished. Memory is up, data is copied and
|
||||
* bss is cleared. Now we call the main routine and
|
||||
* let it do the rest.
|
||||
*/
|
||||
intel_chip_post_macro(0xfe) /* post fe */
|
||||
|
||||
#ifdef SERIAL_CONSOLE
|
||||
TTYS0_TX_STRING($str_pre_main)
|
||||
#endif /* SERIAL_CONSOLE */
|
||||
|
||||
|
||||
/* memory is up. Let\'s do the rest in C -- much easier. */
|
||||
|
||||
/* set new stack */
|
||||
movl $_estack, %esp
|
||||
|
||||
intel_chip_post_macro(0xfd) /* post fe */
|
||||
call EXT(intel_main)
|
||||
/*NOTREACHED*/
|
||||
.Lhlt:
|
||||
intel_chip_post_macro(0xee) /* post fe */
|
||||
hlt
|
||||
jmp .Lhlt
|
||||
|
||||
ttyS0_test: .string "\r\n\r\nHello world!!\r\n"
|
||||
str_after_ram: .string "Ram Initialize?\r\n"
|
||||
str_after_copy: .string "after copy?\r\n"
|
||||
str_pre_main: .string "before main\r\n"
|
||||
newline: .string "\r\n"
|
||||
116
src/arch/i386/config/ldscript.base
Normal file
116
src/arch/i386/config/ldscript.base
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Memory map:
|
||||
*
|
||||
* _RAMBASE
|
||||
* : data segment
|
||||
* : bss segment
|
||||
* : heap
|
||||
* : stack
|
||||
* _ROMBASE
|
||||
* : linuxbios text
|
||||
* : readonly text
|
||||
*/
|
||||
/*
|
||||
* Bootstrap code for the STPC Consumer
|
||||
* Copyright (c) 1999 by Net Insight AB. All Rights Reserved.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Written by Johan Rydberg, based on work by Daniel Kahlin.
|
||||
* Rewritten by Eric Biederman
|
||||
*/
|
||||
/*
|
||||
* We use ELF as output format. So that we can
|
||||
* debug the code in some form.
|
||||
*/
|
||||
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
|
||||
OUTPUT_ARCH(i386)
|
||||
/* oh, barf. This wont work if all you use is .o's. -- RGM */
|
||||
|
||||
|
||||
/* These are now set by the config tool
|
||||
_RAMBASE = 0x04000;
|
||||
_ROMBASE = 0x80000;
|
||||
*/
|
||||
|
||||
/*
|
||||
* Entry point is not really nececary, since the mkrom(8)
|
||||
* tool creates a entry point that jumps to $0xc000:0x0000.
|
||||
*/
|
||||
/* baloney, but ... RGM*/
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/*
|
||||
* First we place the code and read only data (typically const declared).
|
||||
* This get placed in rom.
|
||||
*/
|
||||
.text _ROMBASE : {
|
||||
_text = .;
|
||||
*(.text);
|
||||
_etext = .;
|
||||
}
|
||||
.rodata (.) : {
|
||||
_rodata = .;
|
||||
*(.rodata);
|
||||
_erodata = .;
|
||||
}
|
||||
|
||||
. = _RAMBASE;
|
||||
/*
|
||||
* After the code we place initialized data (typically initialized
|
||||
* global variables). This gets copied into ram by startup code.
|
||||
* __data_start and __data_end shows where in ram this should be placed,
|
||||
* whereas __data_loadstart and __data_loadend shows where in rom to
|
||||
* copy from.
|
||||
*/
|
||||
.data (.): AT (_erodata) {
|
||||
_data = .;
|
||||
*(.data)
|
||||
*(.sdata)
|
||||
*(.sdata2)
|
||||
*(.got)
|
||||
_edata = .;
|
||||
}
|
||||
_ldata = LOADADDR(.data);
|
||||
_eldata = LOADADDR(.data) + SIZEOF(.data);
|
||||
|
||||
/*
|
||||
* bss does not contain data, it is just a space that should be zero
|
||||
* initialized on startup. (typically uninitialized global variables)
|
||||
* crt0.S fills between _bss and _ebss with zeroes.
|
||||
*/
|
||||
.bss (.): {
|
||||
_bss = .;
|
||||
*(.bss)
|
||||
*(.sbss)
|
||||
*(COMMON)
|
||||
_ebss = .;
|
||||
}
|
||||
_end = .;
|
||||
|
||||
.heap (.): {
|
||||
_heap = .;
|
||||
/* Reserve 64K for the heap */
|
||||
. = . + 0x10000;
|
||||
_eheap = .;
|
||||
}
|
||||
.stack (.) : {
|
||||
_stack = .;
|
||||
/* Resever 64k for the stack */
|
||||
. = . + 0x10000;
|
||||
_estack = .;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This provides the start and end address for the whole image
|
||||
*/
|
||||
_image = LOADADDR(.text);
|
||||
_eimage = LOADADDR(.data) + SIZEOF(.data);
|
||||
|
||||
/* EOF */
|
||||
41
src/arch/i386/config/make.base
Normal file
41
src/arch/i386/config/make.base
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
biosbase 0xf0000
|
||||
rambase 0x4000
|
||||
makedefine LINK = ld -T ldscript.ld -o $@ crt0.o linuxbios.a
|
||||
makedefine CPPFLAGS= -I$(TOP)/src/include -I$(TOP)/src/arch/$(ARCH)/include $(CPUFLAGS)
|
||||
makedefine CFLAGS= $(CPU_OPT) $(CPPFLAGS) -O2 -nostdinc -nostdlib -fno-builtin -Wall
|
||||
makedefine CC=cc
|
||||
makerule all : romimage ;
|
||||
makerule floppy : all ; mcopy -o romimage a:
|
||||
makerule romimage : linuxbios.rom vmlinux.bin.gz.block ; cat vmlinux.bin.gz.block linuxbios.rom > romimage
|
||||
makerule linuxbios.rom: linuxbios.strip mkrom ; ./mkrom -s 64 -f -o linuxbios.rom linuxbios.strip
|
||||
makerule linuxbios.strip: linuxbios ; objcopy -O binary -R .note -R .comment -S linuxbios linuxbios.strip
|
||||
makerule linuxbios: linuxbios.a vmlinux.bin.gz ; @rm -f biosobject
|
||||
addaction linuxbios $(LINK)
|
||||
addaction linuxbios nm -n linuxbios > linuxbios.map
|
||||
|
||||
makerule linuxbios.a : $(OBJECTS) ; rm -f linuxbios.a
|
||||
addaction linuxbios.a ar cr linuxbios.a $(OBJECTS)
|
||||
|
||||
makerule crt0.s: crt0.S ; $(CC) $(CPPFLAGS) -I$(TOP)/src -E $< > crt0.s
|
||||
|
||||
makerule crt0.o : crt0.s; $(CC) $(CPU_OPT) -c crt0.s
|
||||
makerule mkrom: $(TOP)/mkrom/mkrom.c ; $(CC) -o mkrom $<
|
||||
|
||||
makerule clean : ; rm -f linuxbios.* vmlinux.* *.o mkrom xa? *~
|
||||
addaction clean rm -f linuxbios romimage crt0.s
|
||||
addaction clean rm -f a.out *.s *.l
|
||||
addaction clean rm -f TAGS tags
|
||||
addaction clean rm -f docipl
|
||||
|
||||
|
||||
makerule vmlinux.bin.gz.block : vmlinux.bin.gz ; dd conv=sync bs=448k if=vmlinux.bin.gz of=vmlinux.bin.gz.block
|
||||
makerule vmlinux.bin.gz: vmlinux.bin ;gzip -f -3 vmlinux.bin
|
||||
makerule vmlinux.bin: $(LINUX)/vmlinux ; objcopy -O binary -R .note -R .comment -S $< vmlinux.bin
|
||||
|
||||
|
||||
# do standard config files that the user need not specify
|
||||
# for now, this is just 'lib', but it may be more later.
|
||||
dir /src/arch/i386
|
||||
dir /src/lib
|
||||
dir /src/boot
|
||||
dir /src/rom
|
||||
1
src/arch/i386/include/arch/io.h
Normal file
1
src/arch/i386/include/arch/io.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
#include <cpu/p5/io.h>
|
||||
3
src/arch/i386/lib/Config
Normal file
3
src/arch/i386/lib/Config
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
object i386_subr.o
|
||||
object params.o
|
||||
object hardwaremain.o
|
||||
197
src/arch/i386/lib/hardwaremain.c
Normal file
197
src/arch/i386/lib/hardwaremain.c
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
This software and ancillary information (herein called SOFTWARE )
|
||||
called LinuxBIOS is made available under the terms described
|
||||
here. The SOFTWARE has been approved for release with associated
|
||||
LA-CC Number 00-34 . Unless otherwise indicated, this SOFTWARE has
|
||||
been authored by an employee or employees of the University of
|
||||
California, operator of the Los Alamos National Laboratory under
|
||||
Contract No. W-7405-ENG-36 with the U.S. Department of Energy. The
|
||||
U.S. Government has rights to use, reproduce, and distribute this
|
||||
SOFTWARE. The public may copy, distribute, prepare derivative works
|
||||
and publicly display this SOFTWARE without charge, provided that this
|
||||
Notice and any statement of authorship are reproduced on all copies.
|
||||
Neither the Government nor the University makes any warranty, express
|
||||
or implied, or assumes any liability or responsibility for the use of
|
||||
this SOFTWARE. If SOFTWARE is modified to produce derivative works,
|
||||
such modified SOFTWARE should be clearly marked, so as not to confuse
|
||||
it with the version available from LANL.
|
||||
*/
|
||||
/* Copyright 2000, Ron Minnich, Advanced Computing Lab, LANL
|
||||
* rminnich@lanl.gov
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* C Bootstrap code for the INTEL
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#define LINUXBIOS
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <cpu/p5/io.h>
|
||||
#include <intel.h>
|
||||
#include <pciconf.h>
|
||||
#include <cpu/p5/cpuid.h>
|
||||
#include <cpu/p6/ioapic.h>
|
||||
#include <subr.h>
|
||||
#include <printk.h>
|
||||
|
||||
void intel_main()
|
||||
{
|
||||
// These are only used here, so don't bother putting them in a .h
|
||||
void mainboard_fixup(void);
|
||||
void nvram_on(void);
|
||||
void keyboard_on(void);
|
||||
void framebuffer_on(void);
|
||||
void intel_copy_irq_routing_table(void);
|
||||
|
||||
#ifdef FINAL_MAINBOARD_FIXUP
|
||||
void final_mainboard_fixup(void);
|
||||
#endif /* FINAL_MAINBOARD_FIXUP */
|
||||
|
||||
#ifdef CONFIGURE_L2_CACHE
|
||||
int intel_l2_configure();
|
||||
#endif /* CONFIGURE_L2_CACHE */
|
||||
|
||||
#ifdef UPDATE_MICROCODE
|
||||
void intel_display_cpuid_microcode(void);
|
||||
#endif /* UPDATE_MICROCODE */
|
||||
|
||||
/* the order here is a bit tricky. We don't want to do much of
|
||||
* anything that uses config registers until after PciAllocateResources
|
||||
* since that function also figures out what kind of config strategy
|
||||
* to use (type 1 or type 2).
|
||||
* so we turn on cache, then worry about PCI setup, then do other
|
||||
* things, so that the other work can use the PciRead* and PciWrite*
|
||||
* functions.
|
||||
*/
|
||||
unsigned long totalram = 0;
|
||||
extern void linuxbiosmain(unsigned long membase, unsigned long totalram);
|
||||
|
||||
/* displayinit MUST PRECEDE ALL PRINTK! */
|
||||
displayinit();
|
||||
|
||||
post_code(0x39);
|
||||
|
||||
printk(KERN_INFO "Reached intel_main().\n");
|
||||
|
||||
post_code(0x40);
|
||||
|
||||
#ifdef UPDATE_MICROCODE
|
||||
post_code(0x41);
|
||||
printk(KERN_INFO "Updating microcode\n");
|
||||
intel_display_cpuid_microcode();
|
||||
#endif /* UPDATE_MICROCODE */
|
||||
post_code(0x42);
|
||||
|
||||
// pick how to scan the bus. This is first so we can get at memory size.
|
||||
printk(KERN_INFO "Finding PCI confiuration type...\n");
|
||||
pci_set_method();
|
||||
post_code(0x5f);
|
||||
|
||||
printk(KERN_INFO "Scanning PCI bus...");
|
||||
pci_enumerate();
|
||||
post_code(0x66);
|
||||
printk(KERN_INFO "done\n");
|
||||
|
||||
// The framebuffer can change how much memory you have.
|
||||
// So you really need to run this before you size ram.
|
||||
#ifdef HAVE_FRAMEBUFFER
|
||||
framebuffer_on();
|
||||
#endif /* HAVE_FRAMEBUFFER */
|
||||
|
||||
totalram = sizeram();
|
||||
post_code(0x70);
|
||||
printk(KERN_INFO "totalram: %ldM\n", totalram/1024);
|
||||
|
||||
// can't size just yet ...
|
||||
// mainboard totalram sizing may not be up yet. If it is not ready,
|
||||
// take a default of 64M
|
||||
if (!totalram)
|
||||
totalram = 64 * 1024;
|
||||
|
||||
// Turn on cache before configuring the bus.
|
||||
printk(KERN_INFO "Enabling cache...");
|
||||
intel_cache_on(0, totalram);
|
||||
post_code(0x80);
|
||||
printk(KERN_INFO "done.\n");
|
||||
|
||||
printk(KERN_INFO "Allocating PCI resources...");
|
||||
// Now do the real bus
|
||||
// we round the total ram up a lot for thing like the SISFB, which
|
||||
// shares high memory with the CPU.
|
||||
pci_configure();
|
||||
post_code(0x88);
|
||||
pci_enable();
|
||||
post_code(0x90);
|
||||
printk(KERN_INFO "done.\n");
|
||||
|
||||
/* set up the IO-APIC for the clock interrupt. */
|
||||
post_code(0x92);
|
||||
setup_ioapic();
|
||||
|
||||
// generic mainboard fixup
|
||||
mainboard_fixup();
|
||||
|
||||
#ifndef MAINBOARD_FIXUP_IN_CHARGE
|
||||
|
||||
nvram_on();
|
||||
|
||||
intel_display_cpuid();
|
||||
intel_mtrr_check();
|
||||
|
||||
#ifndef NO_KEYBOARD
|
||||
keyboard_on();
|
||||
#endif /* NO_KEYBOARD */
|
||||
|
||||
#ifdef MUST_ENABLE_FLOPPY
|
||||
enable_floppy();
|
||||
post_code(0x95);
|
||||
#endif /* MUST_ENABLE_FLOPPY */
|
||||
|
||||
#ifdef SMP
|
||||
/* copy the smp block to address 0 */
|
||||
intel_smpblock((void *)16);
|
||||
post_code(0x96);
|
||||
#endif /* SMP */
|
||||
|
||||
intel_zero_irq_settings();
|
||||
intel_check_irq_routing_table();
|
||||
intel_copy_irq_routing_table();
|
||||
|
||||
post_code(0x9a);
|
||||
|
||||
/* to do: intel_serial_on(); */
|
||||
intel_interrupts_on();
|
||||
|
||||
|
||||
#ifdef FINAL_MAINBOARD_FIXUP
|
||||
printk(KERN_INFO "Final mainboard fixup for ");
|
||||
post_code(0xec);
|
||||
final_mainboard_fixup();
|
||||
printk(KERN_INFO "done.\n");
|
||||
#endif /* FINAL_MAINBOARD_FIXUP */
|
||||
|
||||
#ifdef CONFIGURE_L2_CACHE
|
||||
/* now that everything is really up, enable the l2 cache if desired.
|
||||
* The enable can wait until this point, because linuxbios and it's
|
||||
* data areas are tiny, easily fitting into the L1 cache.
|
||||
*/
|
||||
printk(KERN_INFO "Configuring L2 cache...");
|
||||
intel_l2_configure();
|
||||
printk(KERN_INFO "done.\n");
|
||||
#endif /* CONFIGURE_L2_CACHE */
|
||||
|
||||
#endif /* MAINBOARD_FIXUP_IN_CHARGE */
|
||||
|
||||
#ifdef LINUXBIOS
|
||||
printk(KERN_INFO "Jumping to linuxbiosmain()...\n");
|
||||
// we could go to argc, argv, for main but it seems like overkill.
|
||||
post_code(0xed);
|
||||
linuxbiosmain(0, totalram);
|
||||
#endif /* LINUXBIOS */
|
||||
}
|
||||
163
src/arch/i386/lib/i386_subr.c
Normal file
163
src/arch/i386/lib/i386_subr.c
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
#include <cpu/p5/io.h>
|
||||
#include <cpu/p5/macros.h>
|
||||
#include <cpu/p6/msr.h>
|
||||
|
||||
#include <printk.h>
|
||||
#include <pci.h>
|
||||
#include <subr.h>
|
||||
#include <string.h>
|
||||
|
||||
void intel_cache_on(unsigned long base, unsigned long totalram)
|
||||
{
|
||||
post_code(0x60);
|
||||
|
||||
/* we need an #ifdef i586 here at some point ... */
|
||||
__asm__ __volatile__("mov %cr0, %eax\n\t"
|
||||
"and $0x9fffffff,%eax\n\t"
|
||||
"mov %eax, %cr0\n\t");
|
||||
/* turns out cache isn't really on until you set MTRR registers on
|
||||
* 686 and later.
|
||||
* NOTHING FANCY. Linux does a much better job anyway.
|
||||
* so absolute minimum needed to get it going.
|
||||
*/
|
||||
/* OK, linux it turns out does nothing. We have to do it ... */
|
||||
#ifdef i686
|
||||
// totalram here is in linux sizing, i.e. units of KB.
|
||||
// set_mtrr is responsible for getting it into the right units!
|
||||
intel_set_mtrr(base, totalram);
|
||||
#endif
|
||||
post_code(0x6A);
|
||||
}
|
||||
|
||||
void intel_interrupts_on()
|
||||
{
|
||||
|
||||
/* this is so interrupts work. This is very limited scope --
|
||||
* linux will do better later, we hope ...
|
||||
*/
|
||||
/* this is the first way we learned to do it. It fails on real SMP
|
||||
* stuff. So we have to do things differently ...
|
||||
* see the Intel mp1.4 spec, page A-3
|
||||
*/
|
||||
#ifdef SMP
|
||||
unsigned long reg, *regp;
|
||||
#define SVR 0xfee000f0
|
||||
#define LVT1 0xfee00350
|
||||
#define LVT2 0xfee00360
|
||||
#define APIC_ENABLED 0x100
|
||||
|
||||
printk(KERN_INFO "Enabling interrupts...");
|
||||
|
||||
regp = (unsigned long *) SVR;
|
||||
reg = *regp;
|
||||
reg &= (~0xf0);
|
||||
reg |= APIC_ENABLED;
|
||||
*regp = reg;
|
||||
|
||||
regp = (unsigned long *) LVT1;
|
||||
reg = *regp;
|
||||
reg &= 0xfffe00ff;
|
||||
reg |= 0x5700;
|
||||
*regp = reg;
|
||||
|
||||
regp = (unsigned long *) LVT2;
|
||||
reg = *regp;
|
||||
reg &= 0xfffe00ff;
|
||||
reg |= 0x5400;
|
||||
*regp = reg;
|
||||
#else
|
||||
unsigned long low, high;
|
||||
|
||||
printk(KERN_INFO "Enabling interrupts...");
|
||||
|
||||
rdmsr(0x1b, low, high);
|
||||
low &= ~0x800;
|
||||
wrmsr(0x1b, low, high);
|
||||
#endif
|
||||
|
||||
printk(KERN_INFO "done.\n");
|
||||
post_code(0x9b);
|
||||
}
|
||||
|
||||
|
||||
/* These functions should be chip-set independent -tds */
|
||||
void intel_zero_irq_settings(void)
|
||||
{
|
||||
struct pci_dev *pcidev;
|
||||
unsigned char line;
|
||||
|
||||
printk(KERN_INFO "Zeroing IRQ settings...");
|
||||
|
||||
pcidev = pci_devices;
|
||||
|
||||
while (pcidev) {
|
||||
pci_read_config_byte(pcidev, 0x3d, &line);
|
||||
if (line) {
|
||||
pci_write_config_byte(pcidev, 0x3c, 0);
|
||||
}
|
||||
pcidev = pcidev->next;
|
||||
}
|
||||
printk(KERN_INFO "done.\n");
|
||||
}
|
||||
|
||||
void intel_check_irq_routing_table(void)
|
||||
{
|
||||
#ifdef HAVE_PIRQ_TABLE
|
||||
const u8 *addr;
|
||||
const struct irq_routing_table *rt;
|
||||
int i;
|
||||
u8 sum;
|
||||
|
||||
printk(KERN_INFO "Checking IRQ routing tables...");
|
||||
|
||||
rt = &intel_irq_routing_table;
|
||||
addr = (u8 *)rt;
|
||||
|
||||
sum = 0;
|
||||
for (i = 0; i < rt->size; i++)
|
||||
sum += addr[i];
|
||||
|
||||
DBG("%s:%6d:%s() - irq_routing_table located at: 0x%p\n",
|
||||
__FILE__, __LINE__, __FUNCTION__, addr);
|
||||
|
||||
sum = (unsigned char)(rt->checksum-sum);
|
||||
|
||||
if (sum != rt->checksum) {
|
||||
printk(KERN_WARNING "%s:%6d:%s() - "
|
||||
"checksum is: 0x%02x but should be: 0x%02x\n",
|
||||
__FILE__, __LINE__, __FUNCTION__, rt->checksum, sum);
|
||||
}
|
||||
|
||||
if (rt->signature != PIRQ_SIGNATURE || rt->version != PIRQ_VERSION ||
|
||||
rt->size % 16 || rt->size < sizeof(struct irq_routing_table)) {
|
||||
printk(KERN_WARNING "%s:%6d:%s() - "
|
||||
"Interrupt Routing Table not valid\n",
|
||||
__FILE__, __LINE__, __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
sum = 0;
|
||||
for (i=0; i<rt->size; i++)
|
||||
sum += addr[i];
|
||||
|
||||
if (sum) {
|
||||
printk(KERN_WARNING "%s:%6d:%s() - "
|
||||
"checksum error in irq routing table\n",
|
||||
__FILE__, __LINE__, __FUNCTION__);
|
||||
}
|
||||
|
||||
printk(KERN_INFO "done.\n");
|
||||
#endif /* #ifdef HAVE_PIRQ_TABLE */
|
||||
}
|
||||
|
||||
#define RTABLE_DEST 0xf0000
|
||||
|
||||
void intel_copy_irq_routing_table(void)
|
||||
{
|
||||
#ifdef HAVE_PIRQ_TABLE
|
||||
printk(KERN_INFO "Copying IRQ routing tables...");
|
||||
memcpy((char *) RTABLE_DEST, &intel_irq_routing_table, intel_irq_routing_table.size);
|
||||
printk(KERN_INFO "done.\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
166
src/arch/i386/lib/params.c
Normal file
166
src/arch/i386/lib/params.c
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
#include <string.h>
|
||||
|
||||
/*
|
||||
This software and ancillary information (herein called SOFTWARE )
|
||||
called LinuxBIOS is made available under the terms described
|
||||
here. The SOFTWARE has been approved for release with associated
|
||||
LA-CC Number 00-34 . Unless otherwise indicated, this SOFTWARE has
|
||||
been authored by an employee or employees of the University of
|
||||
California, operator of the Los Alamos National Laboratory under
|
||||
Contract No. W-7405-ENG-36 with the U.S. Department of Energy. The
|
||||
U.S. Government has rights to use, reproduce, and distribute this
|
||||
SOFTWARE. The public may copy, distribute, prepare derivative works
|
||||
and publicly display this SOFTWARE without charge, provided that this
|
||||
Notice and any statement of authorship are reproduced on all copies.
|
||||
Neither the Government nor the University makes any warranty, express
|
||||
or implied, or assumes any liability or responsibility for the use of
|
||||
this SOFTWARE. If SOFTWARE is modified to produce derivative works,
|
||||
such modified SOFTWARE should be clearly marked, so as not to confuse
|
||||
it with the version available from LANL.
|
||||
*/
|
||||
/* Copyright 2000, Ron Minnich, Advanced Computing Lab, LANL
|
||||
* rminnich@lanl.gov
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif
|
||||
|
||||
struct screen_info {
|
||||
unsigned char orig_x; /* 0x00 */
|
||||
unsigned char orig_y; /* 0x01 */
|
||||
unsigned short dontuse1; /* 0x02 -- EXT_MEM_K sits here */
|
||||
unsigned short orig_video_page; /* 0x04 */
|
||||
unsigned char orig_video_mode; /* 0x06 */
|
||||
unsigned char orig_video_cols; /* 0x07 */
|
||||
unsigned short unused2; /* 0x08 */
|
||||
unsigned short orig_video_ega_bx; /* 0x0a */
|
||||
unsigned short unused3; /* 0x0c */
|
||||
unsigned char orig_video_lines; /* 0x0e */
|
||||
unsigned char orig_video_isVGA; /* 0x0f */
|
||||
unsigned short orig_video_points; /* 0x10 */
|
||||
|
||||
/* VESA graphic mode -- linear frame buffer */
|
||||
unsigned short lfb_width; /* 0x12 */
|
||||
unsigned short lfb_height; /* 0x14 */
|
||||
unsigned short lfb_depth; /* 0x16 */
|
||||
unsigned long lfb_base; /* 0x18 */
|
||||
unsigned long lfb_size; /* 0x1c */
|
||||
unsigned short dontuse2, dontuse3; /* 0x20 -- CL_MAGIC and CL_OFFSET here */
|
||||
unsigned short lfb_linelength; /* 0x24 */
|
||||
unsigned char red_size; /* 0x26 */
|
||||
unsigned char red_pos; /* 0x27 */
|
||||
unsigned char green_size; /* 0x28 */
|
||||
unsigned char green_pos; /* 0x29 */
|
||||
unsigned char blue_size; /* 0x2a */
|
||||
unsigned char blue_pos; /* 0x2b */
|
||||
unsigned char rsvd_size; /* 0x2c */
|
||||
unsigned char rsvd_pos; /* 0x2d */
|
||||
unsigned short vesapm_seg; /* 0x2e */
|
||||
unsigned short vesapm_off; /* 0x30 */
|
||||
unsigned short pages; /* 0x32 */
|
||||
/* 0x34 -- 0x3f reserved for future expansion */
|
||||
};
|
||||
|
||||
#define E820MAP 0x2d0 /* our map */
|
||||
#define E820MAX 32 /* number of entries in E820MAP */
|
||||
#define E820NR 0x1e8 /* # entries in E820MAP */
|
||||
|
||||
/* sigh, this is not a struct or include file thing. */
|
||||
#ifdef i386
|
||||
/* from linux 2.2.13 */
|
||||
/*
|
||||
* This is set up by the setup-routine at boot-time
|
||||
*/
|
||||
#define PARAM ((unsigned char *)empty_zero_page)
|
||||
#define SCREEN_INFO (*(struct screen_info *) (PARAM+0))
|
||||
#define EXT_MEM_K (*(unsigned short *) (PARAM+2))
|
||||
#define ALT_MEM_K (*(unsigned long *) (PARAM+0x1e0))
|
||||
#define E820_MAP_NR (*(char*) (PARAM+E820NR))
|
||||
#define E820_MAP ((unsigned long *) (PARAM+E820MAP))
|
||||
#define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+0x40))
|
||||
#define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
|
||||
#define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0xa0))
|
||||
#define MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2))
|
||||
#define RAMDISK_FLAGS (*(unsigned short *) (PARAM+0x1F8))
|
||||
#define ORIG_ROOT_DEV (*(unsigned short *) (PARAM+0x1FC))
|
||||
#define AUX_DEVICE_INFO (*(unsigned char *) (PARAM+0x1FF))
|
||||
#define LOADER_TYPE (*(unsigned char *) (PARAM+0x210))
|
||||
#define KERNEL_START (*(unsigned long *) (PARAM+0x214))
|
||||
#define INITRD_START (*(unsigned long *) (PARAM+0x218))
|
||||
#define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c))
|
||||
#define COMMAND_LINE ((char *) (PARAM+2048))
|
||||
#define COMMAND_LINE_SIZE 256
|
||||
|
||||
#endif
|
||||
/* this is support for passing parameters to the linux kernel.
|
||||
* you can pass memory size, command lines, and so on.
|
||||
*/
|
||||
|
||||
void
|
||||
init_params(unsigned char *empty_zero_page)
|
||||
{
|
||||
memset(PARAM, 0, 4096 /*XXXXXXXXXXXXXXXXX */ );
|
||||
}
|
||||
|
||||
void
|
||||
set_memory_size(unsigned char *empty_zero_page, unsigned long ext_memory_size,
|
||||
unsigned long alt_memory_size)
|
||||
{
|
||||
/* for now, we do not have an 820 map (who cares, 8x0 chipsets are dead! */
|
||||
E820_MAP_NR = 0;
|
||||
EXT_MEM_K = ext_memory_size;
|
||||
ALT_MEM_K = alt_memory_size;
|
||||
}
|
||||
|
||||
void
|
||||
set_root_rdonly(unsigned char *empty_zero_page)
|
||||
{
|
||||
MOUNT_ROOT_RDONLY = 1;
|
||||
}
|
||||
|
||||
/* see the lilo doc */
|
||||
void
|
||||
set_command_line(unsigned char *empty_zero_page, unsigned char *cmdline)
|
||||
{
|
||||
int i;
|
||||
/* no strncpy ...
|
||||
strncpy(COMMAND_LINE, cmdline, COMMAND_LINE_SIZE);
|
||||
*/
|
||||
for (i = 0; (i < COMMAND_LINE_SIZE) && (cmdline[i]); i++)
|
||||
COMMAND_LINE[i] = cmdline[i];
|
||||
*(unsigned short *) 0x90020 = 0xa33f;
|
||||
*(unsigned short *) 0x90022 = 2048;
|
||||
}
|
||||
|
||||
unsigned char *
|
||||
get_empty_zero_page()
|
||||
{
|
||||
/* gosh, I thought we had to do get at empty_zero_page, and we don't.
|
||||
* silly me. We just have to get to 0x90000
|
||||
*/
|
||||
/* we'll leave this hook in for now. We may need it someday */
|
||||
// unsigned long l = *(unsigned long *) 0xffffc;
|
||||
|
||||
return (unsigned char *) 0x90000;
|
||||
}
|
||||
|
||||
/* I am pretty sure we only need to set rows and cols for now.
|
||||
* All the rest is BIOS stuff. If it gets worse we'll have to make this a
|
||||
* screen_info * as the param
|
||||
*/
|
||||
void
|
||||
set_display(unsigned char *empty_zero_page, int rows, int cols)
|
||||
{
|
||||
struct screen_info *sc = &SCREEN_INFO;
|
||||
sc->orig_video_cols = cols;
|
||||
sc->orig_video_lines = rows;
|
||||
}
|
||||
|
||||
void
|
||||
set_initrd(unsigned char *empty_zero_page, unsigned long start, unsigned long size)
|
||||
{
|
||||
INITRD_START = start;
|
||||
INITRD_SIZE = size;
|
||||
LOADER_TYPE = 1;
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
/* Standard ELF types. */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <arch/boot/boot.h>
|
||||
|
||||
/* Type for a 16-bit quantity. */
|
||||
|
|
@ -390,4 +391,5 @@ typedef Elf64_Phdr Elf_phdr;
|
|||
|
||||
extern int elf_check_arch(Elf_ehdr *ehdr);
|
||||
extern void jmp_to_elf_entry(void *entry, void *ube);
|
||||
extern int elfboot(size_t totalram);
|
||||
#endif /* elf.h */
|
||||
|
|
|
|||
13
src/include/rom/fill_inbuf.h
Normal file
13
src/include/rom/fill_inbuf.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef ROM_FILL_INBUF_H
|
||||
#define ROM_FILL_INBUF_H
|
||||
|
||||
extern unsigned char *inbuf; /* input buffer */
|
||||
extern unsigned int insize; /* valid bytes in inbuf */
|
||||
extern unsigned int inptr; /* index of next byte to be processed in inbuf */
|
||||
|
||||
extern int fill_inbuf(void);
|
||||
|
||||
#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
|
||||
|
||||
|
||||
#endif /* ROM_FILL_INBUF_H */
|
||||
|
|
@ -6,4 +6,9 @@
|
|||
extern void *malloc(size_t size);
|
||||
void free(void *ptr);
|
||||
|
||||
/* Extensions to malloc... */
|
||||
typedef size_t malloc_mark_t;
|
||||
void malloc_mark(malloc_mark_t *place);
|
||||
void malloc_release(malloc_mark_t *place);
|
||||
|
||||
#endif /* STDLIB_H */
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
#ifndef STRING_H
|
||||
#define STRING_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
// yes, linux has fancy ones. We don't care. This stuff gets used
|
||||
// hardly at all. And the pain of including those files is just too high.
|
||||
|
||||
|
|
@ -5,8 +10,7 @@
|
|||
|
||||
//extern inline int strlen(char *src) { int i = 0; while (*src++) i++; return i;}
|
||||
|
||||
#if 1
|
||||
extern inline int strnlen(const char *src, int max) {
|
||||
static inline size_t strnlen(const char *src, size_t max) {
|
||||
int i = 0;
|
||||
if (max<0) {
|
||||
while (*src++)
|
||||
|
|
@ -19,23 +23,9 @@ extern inline int strnlen(const char *src, int max) {
|
|||
return i;
|
||||
}
|
||||
}
|
||||
#else
|
||||
static inline size_t strnlen(const char * s, size_t count)
|
||||
{
|
||||
int d0;
|
||||
register int __res;
|
||||
__asm__ __volatile__(
|
||||
"movl %2,%0\n\t"
|
||||
"jmp 2f\n"
|
||||
"1:\tcmpb $0,(%0)\n\t"
|
||||
"je 3f\n\t"
|
||||
"incl %0\n"
|
||||
"2:\tdecl %1\n\t"
|
||||
"cmpl $-1,%1\n\t"
|
||||
"jne 1b\n"
|
||||
"3:\tsubl %2,%0"
|
||||
:"=a" (__res), "=&d" (d0)
|
||||
:"c" (s),"1" (count));
|
||||
return __res;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern void *memcpy(void *dest, const void *src, size_t n);
|
||||
extern void *memset(void *s, int c, size_t n);
|
||||
extern int memcmp(const void *s1, const void *s2, size_t n);
|
||||
|
||||
#endif /* STRING_H */
|
||||
|
|
|
|||
101
src/lib/do_inflate.c
Normal file
101
src/lib/do_inflate.c
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
#include <printk.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <rom/fill_inbuf.h>
|
||||
#include <subr.h>
|
||||
#include "definitions.h"
|
||||
#include "do_inflate.h"
|
||||
|
||||
#define MALLOC_WINDOW 1
|
||||
/*
|
||||
* gzip support routine declartions..
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
static void flush_window(void);
|
||||
|
||||
static long bytes_out; /* total bytes compressed */
|
||||
static unsigned outcnt; /* bytes in output buffer */
|
||||
|
||||
#define WSIZE 0x8000 /* Window size must be at least 32k, and a power of two */
|
||||
#if !MALLOC_WINDOW
|
||||
static unsigned char window[WSIZE]; /* Sliding window buffer */
|
||||
#else
|
||||
static unsigned char *window; /* Sliding window buffer */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* gzip declarations
|
||||
*/
|
||||
|
||||
#define OF(args) args
|
||||
#define STATIC static
|
||||
|
||||
|
||||
#define memzero(s, n) memset ((s), 0, (n))
|
||||
|
||||
typedef unsigned char uch;
|
||||
typedef unsigned short ush;
|
||||
typedef unsigned long ulg;
|
||||
|
||||
|
||||
#ifdef TRACEV
|
||||
# define Trace(x) printk(KERN_DDEBUG x)
|
||||
# define Tracev(x) {if (verbose) printk(KERN_DDEBUG x);}
|
||||
# define Tracevv(x) {if (verbose>1) printk(KERN_DDEBUG x);}
|
||||
# define Tracec(c,x) {if (verbose && (c)) printk(KERN_DDEBUG x);}
|
||||
# define Tracecv(c,x) {if (verbose>1 && (c)) printk(KERN_DDEBUG x);}
|
||||
#else
|
||||
# define Trace(x)
|
||||
# define Tracev(x)
|
||||
# define Tracevv(x)
|
||||
# define Tracec(c,x)
|
||||
# define Tracecv(c,x)
|
||||
#endif
|
||||
|
||||
#include "inflate.c"
|
||||
|
||||
/* Variables that gunzip doesn't need to see... */
|
||||
static unsigned char *output_data;
|
||||
static unsigned long output_ptr;
|
||||
|
||||
|
||||
/* ===========================================================================
|
||||
* Write the output window window[0..outcnt-1] and update crc and bytes_out.
|
||||
* (Used for the decompressed data only.)
|
||||
*/
|
||||
static void flush_window(void)
|
||||
{
|
||||
ulg c = crc; /* temporary variable */
|
||||
unsigned n;
|
||||
uch *in, *out, ch;
|
||||
|
||||
in = window;
|
||||
out = &output_data[output_ptr];
|
||||
DBG("flush 0x%08x count 0x%08x\n", (unsigned long) out, outcnt);
|
||||
|
||||
for (n = 0; n < outcnt; n++) {
|
||||
ch = *out++ = *in++;
|
||||
c = crc_32_tab[((int) c ^ ch) & 0xff] ^ (c >> 8);
|
||||
}
|
||||
crc = c;
|
||||
bytes_out += (ulg) outcnt;
|
||||
output_ptr += (ulg) outcnt;
|
||||
outcnt = 0;
|
||||
}
|
||||
|
||||
void gunzip_setup(void)
|
||||
{
|
||||
/* common globals -- don't rely on init! */
|
||||
outcnt = 0;
|
||||
bytes_out = 0;
|
||||
output_ptr = 0;
|
||||
|
||||
#if MALLOC_WINDOW
|
||||
window = malloc(WSIZE);
|
||||
#endif
|
||||
output_data = (char *) KERNEL_START;
|
||||
DBG("output data is 0x%08x\n", (unsigned long) output_data);
|
||||
makecrc();
|
||||
}
|
||||
6
src/lib/do_inflate.h
Normal file
6
src/lib/do_inflate.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef DO_INFLATE_H
|
||||
#define DO_INFLATE_H
|
||||
|
||||
extern void gunzip_setup(void);
|
||||
extern int gunzip(void);
|
||||
#endif /* DO_INFLATE_H */
|
||||
144
src/lib/elfboot.c
Normal file
144
src/lib/elfboot.c
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
#if USE_ELF_BOOT
|
||||
#include <printk.h>
|
||||
#include <boot/elf.h>
|
||||
#include <boot/uniform_boot.h>
|
||||
#include <rom/fill_inbuf.h>
|
||||
#include <string.h>
|
||||
#include <subr.h>
|
||||
|
||||
int elfboot(size_t totalram)
|
||||
{
|
||||
static unsigned char header[ELF_HEAD_SIZE];
|
||||
unsigned long offset;
|
||||
Elf_ehdr *ehdr;
|
||||
Elf_phdr *phdr;
|
||||
void *ptr, *entry;
|
||||
int i;
|
||||
|
||||
printk("\n");
|
||||
printk("Welcome to elfboot, the open sourced starter.\n");
|
||||
printk("Febuary 2001, Eric Biederman.\n");
|
||||
printk("Version 0.99\n");
|
||||
printk("\n");
|
||||
ptr = get_ube_pointer(totalram);
|
||||
|
||||
post_code(0xf8);
|
||||
/* Read in the initial 512 bytes */
|
||||
for(offset = 0; offset < 512; offset++) {
|
||||
header[offset] = get_byte();
|
||||
}
|
||||
ehdr = (Elf_ehdr *)(&header[0]);
|
||||
entry = (void *)(ehdr->e_entry);
|
||||
|
||||
/* Sanity check the elf header */
|
||||
if ((memcmp(ehdr->e_ident, ELFMAG, 4) != 0) ||
|
||||
(ehdr->e_type != ET_EXEC) ||
|
||||
(!elf_check_arch(ehdr)) ||
|
||||
(ehdr->e_ident[EI_VERSION] != EV_CURRENT) ||
|
||||
(ehdr->e_version != EV_CURRENT) ||
|
||||
(ehdr->e_phoff > ELF_HEAD_SIZE) ||
|
||||
(ehdr->e_phentsize != sizeof(Elf_phdr)) ||
|
||||
((ehdr->e_phoff + (ehdr->e_phentsize * ehdr->e_phnum)) >
|
||||
ELF_HEAD_SIZE)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
phdr = (Elf_phdr *)&header[ehdr->e_phoff];
|
||||
offset = 0;
|
||||
while(1) {
|
||||
Elf_phdr *cur_phdr = 0;
|
||||
int i,len;
|
||||
unsigned long start_offset;
|
||||
unsigned char *dest, *middle, *end;
|
||||
/* Find the program header that descibes the current piece
|
||||
* of the file.
|
||||
*/
|
||||
for(i = 0; i < ehdr->e_phnum; i++) {
|
||||
if (phdr[i].p_type != PT_LOAD) {
|
||||
continue;
|
||||
}
|
||||
if (phdr[i].p_filesz > phdr[i].p_memsz) {
|
||||
continue;
|
||||
}
|
||||
if (phdr[i].p_offset >= offset) {
|
||||
if (!cur_phdr ||
|
||||
(cur_phdr->p_offset > phdr[i].p_offset)) {
|
||||
cur_phdr = &phdr[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If we are out of sections we are done */
|
||||
if (!cur_phdr) {
|
||||
break;
|
||||
}
|
||||
printk("Loading Section: addr: 0x%08x memsz: 0x%08x filesz: 0x%08x\n",
|
||||
cur_phdr->p_paddr, cur_phdr->p_memsz, cur_phdr->p_filesz);
|
||||
|
||||
/* Compute the boundaries of the section */
|
||||
dest = (unsigned char *)(cur_phdr->p_paddr);
|
||||
end = dest + cur_phdr->p_memsz;
|
||||
len = cur_phdr->p_filesz;
|
||||
if (len > cur_phdr->p_memsz) {
|
||||
len = cur_phdr->p_memsz;
|
||||
}
|
||||
middle = dest + len;
|
||||
start_offset = cur_phdr->p_offset;
|
||||
|
||||
/* Skip intial buffer unused bytes */
|
||||
if (offset < ELF_HEAD_SIZE) {
|
||||
if (start_offset < ELF_HEAD_SIZE) {
|
||||
offset = start_offset;
|
||||
} else {
|
||||
offset = ELF_HEAD_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip the unused bytes */
|
||||
while(offset < start_offset) {
|
||||
offset++;
|
||||
get_byte();
|
||||
}
|
||||
|
||||
/* Copy data from the initial buffer */
|
||||
if (offset < ELF_HEAD_SIZE) {
|
||||
size_t len;
|
||||
if ((cur_phdr->p_filesz + start_offset) > ELF_HEAD_SIZE) {
|
||||
len = ELF_HEAD_SIZE - start_offset;
|
||||
}
|
||||
else {
|
||||
len = cur_phdr->p_filesz;
|
||||
}
|
||||
memcpy(dest, &header[start_offset], len);
|
||||
dest += len;
|
||||
}
|
||||
|
||||
/* Read the section into memory */
|
||||
while(dest < middle) {
|
||||
*(dest++) = get_byte();
|
||||
}
|
||||
offset += cur_phdr->p_filesz;
|
||||
/* Zero the extra bytes */
|
||||
while(dest < end) {
|
||||
*(dest++) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
DBG("Jumping to boot code\n");
|
||||
post_code(0xfe);
|
||||
|
||||
/* Jump to kernel */
|
||||
jmp_to_elf_entry(entry, ptr);
|
||||
|
||||
out:
|
||||
printk("Bad ELF Image\n");
|
||||
for(i = 0; i < sizeof(*ehdr); i++) {
|
||||
if ((i & 0xf) == 0) {
|
||||
printk("\n");
|
||||
}
|
||||
printk("%02x ", header[i]);
|
||||
}
|
||||
printk("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* USE_ELF_BOOT */
|
||||
|
|
@ -1,8 +1,5 @@
|
|||
#define DEBG(x)
|
||||
#define DEBGINT(x)
|
||||
#define DEBG1(x)
|
||||
#define DEBGH(x)
|
||||
#define DEBGDYN(x)
|
||||
/* Taken from /usr/src/linux/lib/inflate.c [unmodified]
|
||||
Used for start32, 1/11/2000
|
||||
James Hendricks, Dale Webster */
|
||||
|
|
@ -13,6 +10,12 @@
|
|||
/*
|
||||
* Adapted for booting Linux by Hannu Savolainen 1993
|
||||
* based on gzip-1.0.3
|
||||
*
|
||||
* Nicolas Pitre <nico@cam.org>, 1999/04/14 :
|
||||
* Little mods for all variable to reside either into rodata or bss segments
|
||||
* by marking constant variables with 'const' and initializing all the others
|
||||
* at run-time only. This allows for the kernel uncompressor to run
|
||||
* directly from Flash or ROM memory on embeded systems.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
@ -115,7 +118,6 @@ static char rcsid[] = "#Id: inflate.c,v 0.14 1993/06/10 13:27:04 jloup Exp #";
|
|||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "gzip.h"
|
||||
#define STATIC
|
||||
#endif /* !STATIC */
|
||||
|
|
@ -140,8 +142,8 @@ struct huft {
|
|||
|
||||
|
||||
/* Function prototypes */
|
||||
STATIC int huft_build OF((unsigned *, unsigned, unsigned, const ush *,
|
||||
const ush *, struct huft **, int *));
|
||||
STATIC int huft_build OF((unsigned *, unsigned, unsigned,
|
||||
const ush *, const ush *, struct huft **, int *));
|
||||
STATIC int huft_free OF((struct huft *));
|
||||
STATIC int inflate_codes OF((struct huft *, struct huft *, int, int));
|
||||
STATIC int inflate_stored OF((void));
|
||||
|
|
@ -164,20 +166,20 @@ STATIC int inflate OF((void));
|
|||
#define flush_output(w) (wp=(w),flush_window())
|
||||
|
||||
/* Tables for deflate from PKZIP's appnote.txt. */
|
||||
const unsigned border[] = { /* Order of the bit length code lengths */
|
||||
static const unsigned 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};
|
||||
const ush cplens[] = { /* Copy lengths for literal codes 257..285 */
|
||||
static const ush 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};
|
||||
/* note: see note #13 above about the 258 in this list. */
|
||||
const ush cplext[] = { /* Extra bits for literal codes 257..285 */
|
||||
static const ush 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, 99, 99}; /* 99==invalid */
|
||||
const ush cpdist[] = { /* Copy offsets for distance codes 0..29 */
|
||||
static const ush 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};
|
||||
const ush cpdext[] = { /* Extra bits for distance codes */
|
||||
static const ush 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};
|
||||
|
|
@ -217,7 +219,7 @@ const ush cpdext[] = { /* Extra bits for distance codes */
|
|||
STATIC ulg bb; /* bit buffer */
|
||||
STATIC unsigned bk; /* bits in bit buffer */
|
||||
|
||||
const ush mask_bits[] = {
|
||||
STATIC const ush mask_bits[] = {
|
||||
0x0000,
|
||||
0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
|
||||
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
|
||||
|
|
@ -261,8 +263,8 @@ const ush mask_bits[] = {
|
|||
*/
|
||||
|
||||
|
||||
STATIC int lbits ; /* bits in base literal/length lookup table */
|
||||
STATIC int dbits ; /* bits in base distance lookup table */
|
||||
STATIC const int lbits = 9; /* bits in base literal/length lookup table */
|
||||
STATIC const int dbits = 6; /* bits in base distance lookup table */
|
||||
|
||||
|
||||
/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
|
||||
|
|
@ -273,14 +275,14 @@ STATIC int dbits ; /* bits in base distance lookup table */
|
|||
STATIC unsigned hufts; /* track memory usage */
|
||||
|
||||
|
||||
STATIC int huft_build(
|
||||
unsigned *b, /* code lengths in bits (all assumed <= BMAX) */
|
||||
unsigned n, /* number of codes (assumed <= N_MAX) */
|
||||
unsigned s, /* number of simple-valued codes (0..s-1) */
|
||||
const ush *d, /* list of base values for non-simple codes */
|
||||
const ush *e, /* list of extra bits for non-simple codes */
|
||||
struct huft **t, /* result: starting table */
|
||||
int *m) /* maximum lookup bits, returns actual */
|
||||
STATIC int huft_build(b, n, s, d, e, t, m)
|
||||
unsigned *b; /* code lengths in bits (all assumed <= BMAX) */
|
||||
unsigned n; /* number of codes (assumed <= N_MAX) */
|
||||
unsigned s; /* number of simple-valued codes (0..s-1) */
|
||||
const ush *d; /* list of base values for non-simple codes */
|
||||
const ush *e; /* list of extra bits for non-simple codes */
|
||||
struct huft **t; /* result: starting table */
|
||||
int *m; /* maximum lookup bits, returns actual */
|
||||
/* Given a list of code lengths and a maximum table size, make a set of
|
||||
tables to decode that set of codes. Return zero on success, one if
|
||||
the given code set is incomplete (the tables are still built in this
|
||||
|
|
@ -307,7 +309,7 @@ STATIC int huft_build(
|
|||
int y; /* number of dummy codes added */
|
||||
unsigned z; /* number of entries in current table */
|
||||
|
||||
DEBGH("huft1 ");
|
||||
DEBG("huft1 ");
|
||||
|
||||
/* Generate counts for each bit length */
|
||||
memzero(c, sizeof(c));
|
||||
|
|
@ -320,12 +322,12 @@ DEBGH("huft1 ");
|
|||
} while (--i);
|
||||
if (c[0] == n) /* null input--all zero length codes */
|
||||
{
|
||||
*t = 0;
|
||||
*t = (struct huft *)NULL;
|
||||
*m = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEBGH("huft2 ");
|
||||
DEBG("huft2 ");
|
||||
|
||||
/* Find minimum and maximum length, bound *m by those */
|
||||
l = *m;
|
||||
|
|
@ -343,7 +345,7 @@ DEBGH("huft2 ");
|
|||
l = i;
|
||||
*m = l;
|
||||
|
||||
DEBGH("huft3 ");
|
||||
DEBG("huft3 ");
|
||||
|
||||
/* Adjust last length count to fill out codes, if needed */
|
||||
for (y = 1 << j; j < i; j++, y <<= 1)
|
||||
|
|
@ -353,7 +355,7 @@ DEBGH("huft3 ");
|
|||
return 2;
|
||||
c[i] += y;
|
||||
|
||||
DEBGH("huft4 ");
|
||||
DEBG("huft4 ");
|
||||
|
||||
/* Generate starting offsets into the value table for each length */
|
||||
x[1] = j = 0;
|
||||
|
|
@ -362,7 +364,7 @@ DEBGH("huft4 ");
|
|||
*xp++ = (j += *p++);
|
||||
}
|
||||
|
||||
DEBGH("huft5 ");
|
||||
DEBG("huft5 ");
|
||||
|
||||
/* Make a table of values in order of bit lengths */
|
||||
p = b; i = 0;
|
||||
|
|
@ -371,26 +373,26 @@ DEBGH("huft5 ");
|
|||
v[x[j]++] = i;
|
||||
} while (++i < n);
|
||||
|
||||
DEBGH("h6 ");
|
||||
DEBG("h6 ");
|
||||
|
||||
/* 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] = 0; /* just to keep compilers happy */
|
||||
q = (struct huft *)0; /* ditto */
|
||||
u[0] = (struct huft *)NULL; /* just to keep compilers happy */
|
||||
q = (struct huft *)NULL; /* ditto */
|
||||
z = 0; /* ditto */
|
||||
DEBGH("h6a ");
|
||||
DEBG("h6a ");
|
||||
|
||||
/* go through the bit lengths (k already is bits in shortest code) */
|
||||
for (; k <= g; k++)
|
||||
{
|
||||
DEBGH("h6b ");
|
||||
DEBG("h6b ");
|
||||
a = c[k];
|
||||
while (a--)
|
||||
{
|
||||
DEBGH("h6b1 ");
|
||||
DEBG("h6b1 ");
|
||||
/* here i is the Huffman code of length k bits for value *p */
|
||||
/* make tables up to required level */
|
||||
while (k > w + l)
|
||||
|
|
@ -417,7 +419,8 @@ DEBG1("3 ");
|
|||
z = 1 << j; /* table entries for j-bit table */
|
||||
|
||||
/* allocate and link in new table */
|
||||
if ((q = (struct huft *)malloc((z + 1)*sizeof(struct huft))) == 0)
|
||||
if ((q = (struct huft *)malloc((z + 1)*sizeof(struct huft))) ==
|
||||
(struct huft *)NULL)
|
||||
{
|
||||
if (h)
|
||||
huft_free(u[0]);
|
||||
|
|
@ -426,7 +429,7 @@ DEBG1("3 ");
|
|||
DEBG1("4 ");
|
||||
hufts += z + 1; /* track memory usage */
|
||||
*t = q + 1; /* link to list for huft_free() */
|
||||
*(t = &(q->v.t)) = 0;
|
||||
*(t = &(q->v.t)) = (struct huft *)NULL;
|
||||
u[h] = ++q; /* table starts after link */
|
||||
|
||||
DEBG1("5 ");
|
||||
|
|
@ -442,7 +445,7 @@ DEBG1("5 ");
|
|||
}
|
||||
DEBG1("6 ");
|
||||
}
|
||||
DEBGH("h6c ");
|
||||
DEBG("h6c ");
|
||||
|
||||
/* set up table entry in r */
|
||||
r.b = (uch)(k - w);
|
||||
|
|
@ -459,7 +462,7 @@ DEBGH("h6c ");
|
|||
r.e = (uch)e[*p - s]; /* non-simple--look up in lists */
|
||||
r.v.n = d[*p++ - s];
|
||||
}
|
||||
DEBGH("h6d ");
|
||||
DEBG("h6d ");
|
||||
|
||||
/* fill code-like entries with r */
|
||||
f = 1 << (k - w);
|
||||
|
|
@ -477,12 +480,12 @@ DEBGH("h6d ");
|
|||
h--; /* don't need to update q */
|
||||
w -= l;
|
||||
}
|
||||
DEBGH("h6e ");
|
||||
DEBG("h6e ");
|
||||
}
|
||||
DEBGH("h6f ");
|
||||
DEBG("h6f ");
|
||||
}
|
||||
|
||||
DEBGH("huft7 ");
|
||||
DEBG("huft7 ");
|
||||
|
||||
/* Return true (1) if we were given an incomplete table */
|
||||
return y != 0 && g != 1;
|
||||
|
|
@ -490,8 +493,8 @@ DEBGH("huft7 ");
|
|||
|
||||
|
||||
|
||||
STATIC int huft_free(
|
||||
struct huft *t) /* table to free */
|
||||
STATIC int huft_free(t)
|
||||
struct huft *t; /* table to free */
|
||||
/* 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. */
|
||||
|
|
@ -501,7 +504,7 @@ struct huft *t) /* table to free */
|
|||
|
||||
/* Go through linked list, freeing from the malloced (t[-1]) address. */
|
||||
p = t;
|
||||
while (p != 0)
|
||||
while (p != (struct huft *)NULL)
|
||||
{
|
||||
q = (--p)->v.t;
|
||||
free((char*)p);
|
||||
|
|
@ -511,11 +514,9 @@ struct huft *t) /* table to free */
|
|||
}
|
||||
|
||||
|
||||
STATIC int inflate_codes(
|
||||
struct huft *tl,
|
||||
struct huft *td, /* literal/length and distance decoder tables */
|
||||
int bl,
|
||||
int bd) /* number of bits decoded by tl[] and td[] */
|
||||
STATIC int inflate_codes(tl, td, bl, bd)
|
||||
struct huft *tl, *td; /* literal/length and distance decoder tables */
|
||||
int bl, bd; /* number of bits decoded by tl[] and td[] */
|
||||
/* inflate (decompress) the codes in a deflated (compressed) block.
|
||||
Return an error code or zero if it all goes ok. */
|
||||
{
|
||||
|
|
@ -550,9 +551,6 @@ STATIC int inflate_codes(
|
|||
DUMPBITS(t->b)
|
||||
if (e == 16) /* then it's a literal */
|
||||
{
|
||||
/*
|
||||
DEBG("l");
|
||||
*/
|
||||
slide[w++] = (uch)t->v.n;
|
||||
Tracevv((stderr, "%c", slide[w-1]));
|
||||
if (w == WSIZE)
|
||||
|
|
@ -587,18 +585,10 @@ STATIC int inflate_codes(
|
|||
d = w - t->v.n - ((unsigned)b & mask_bits[e]);
|
||||
DUMPBITS(e)
|
||||
Tracevv((stderr,"\\[%d,%d]", w-d, n));
|
||||
/*
|
||||
DEBG("D");printint(w-d);printint(n);
|
||||
*/
|
||||
|
||||
/* do the copy */
|
||||
do {
|
||||
n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
|
||||
#if 0
|
||||
DEBG("memcpy %d to %d size %d"); printint(d); printint(w);
|
||||
printint(e);
|
||||
DEBG("\n");
|
||||
#endif
|
||||
#if !defined(NOMEMCPY) && !defined(DEBUG)
|
||||
if (w - d >= e) /* (this test assumes unsigned comparison) */
|
||||
{
|
||||
|
|
@ -633,7 +623,7 @@ STATIC int inflate_codes(
|
|||
|
||||
|
||||
|
||||
STATIC int inflate_stored(void)
|
||||
STATIC int inflate_stored()
|
||||
/* "decompress" an inflated type 0 (stored) block. */
|
||||
{
|
||||
unsigned n; /* number of bytes in block */
|
||||
|
|
@ -689,7 +679,7 @@ DEBG("<stor");
|
|||
|
||||
|
||||
|
||||
STATIC int inflate_fixed(void)
|
||||
STATIC int inflate_fixed()
|
||||
/* decompress an inflated type 1 (fixed Huffman codes) block. We should
|
||||
either replace this with a custom decoder, or at least precompute the
|
||||
Huffman tables. */
|
||||
|
|
@ -743,7 +733,7 @@ DEBG("<fix");
|
|||
|
||||
|
||||
|
||||
STATIC int inflate_dynamic(void)
|
||||
STATIC int inflate_dynamic()
|
||||
/* decompress an inflated type 2 (dynamic Huffman codes) block. */
|
||||
{
|
||||
int i; /* temporary variables */
|
||||
|
|
@ -766,14 +756,6 @@ STATIC int inflate_dynamic(void)
|
|||
register ulg b; /* bit buffer */
|
||||
register unsigned k; /* number of bits in bit buffer */
|
||||
|
||||
|
||||
#if 0
|
||||
for(i = 0; i < 288+32; i++)
|
||||
if (ll[i]) {
|
||||
display("non-zero ll index at ");
|
||||
printint(i);
|
||||
}
|
||||
#endif
|
||||
DEBG("<dyn");
|
||||
|
||||
/* make local bit buffer */
|
||||
|
|
@ -797,8 +779,8 @@ DEBG("<dyn");
|
|||
if (nl > 286 || nd > 30)
|
||||
#endif
|
||||
return 1; /* bad lengths */
|
||||
DEBGINT(nl); DEBGINT(nd); DEBGINT(nb);
|
||||
DEBGDYN("dyn1 ");
|
||||
|
||||
DEBG("dyn1 ");
|
||||
|
||||
/* read in bit-length-code lengths */
|
||||
for (j = 0; j < nb; j++)
|
||||
|
|
@ -810,17 +792,18 @@ DEBGDYN("dyn1 ");
|
|||
for (; j < 19; j++)
|
||||
ll[border[j]] = 0;
|
||||
|
||||
DEBG("dyn2 ");
|
||||
|
||||
/* build decoding table for trees--single level, 7 bit lookup */
|
||||
bl = 7;
|
||||
if ((i = huft_build(ll, 19, 19, 0, 0, &tl, &bl)) != 0)
|
||||
if ((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl)) != 0)
|
||||
{
|
||||
if (i == 1)
|
||||
huft_free(tl);
|
||||
return i; /* incomplete code set */
|
||||
}
|
||||
|
||||
DEBGDYN("dyn3 freemem now "); DEBGINT(free_mem_ptr);
|
||||
DEBG("dyn3 ");
|
||||
|
||||
/* read in literal and distance code lengths */
|
||||
n = nl + nd;
|
||||
|
|
@ -832,9 +815,6 @@ DEBGDYN("dyn3 freemem now "); DEBGINT(free_mem_ptr);
|
|||
j = (td = tl + ((unsigned)b & m))->b;
|
||||
DUMPBITS(j)
|
||||
j = td->v.n;
|
||||
/*
|
||||
DEBGDYN("j is now"); DEBGINT(j);
|
||||
*/
|
||||
if (j < 16) /* length of code in bits (0..15) */
|
||||
ll[i++] = l = j; /* save last length in l */
|
||||
else if (j == 16) /* repeat last length 3 to 6 times */
|
||||
|
|
@ -842,9 +822,6 @@ DEBGDYN("dyn3 freemem now "); DEBGINT(free_mem_ptr);
|
|||
NEEDBITS(2)
|
||||
j = 3 + ((unsigned)b & 3);
|
||||
DUMPBITS(2)
|
||||
/*
|
||||
DEBGDYN("j second is now"); DEBGINT(j);
|
||||
*/
|
||||
if ((unsigned)i + j > n)
|
||||
return 1;
|
||||
while (j--)
|
||||
|
|
@ -855,9 +832,6 @@ DEBGDYN("dyn3 freemem now "); DEBGINT(free_mem_ptr);
|
|||
NEEDBITS(3)
|
||||
j = 3 + ((unsigned)b & 7);
|
||||
DUMPBITS(3)
|
||||
/*
|
||||
DEBGDYN("j three is now"); DEBGINT(j);
|
||||
*/
|
||||
if ((unsigned)i + j > n)
|
||||
return 1;
|
||||
while (j--)
|
||||
|
|
@ -869,9 +843,6 @@ DEBGDYN("dyn3 freemem now "); DEBGINT(free_mem_ptr);
|
|||
NEEDBITS(7)
|
||||
j = 11 + ((unsigned)b & 0x7f);
|
||||
DUMPBITS(7)
|
||||
/*
|
||||
DEBGDYN("j four is now"); DEBGINT(j);
|
||||
*/
|
||||
if ((unsigned)i + j > n)
|
||||
return 1;
|
||||
while (j--)
|
||||
|
|
@ -880,35 +851,35 @@ DEBGDYN("dyn3 freemem now "); DEBGINT(free_mem_ptr);
|
|||
}
|
||||
}
|
||||
|
||||
DEBGDYN("dyn4 ");
|
||||
DEBG("dyn4 ");
|
||||
|
||||
/* free decoding table for trees */
|
||||
huft_free(tl);
|
||||
|
||||
DEBGDYN("dyn5 free mem is now");DEBGINT(free_mem_ptr);
|
||||
DEBG("dyn5 ");
|
||||
|
||||
/* restore the global bit buffer */
|
||||
bb = b;
|
||||
bk = k;
|
||||
|
||||
DEBGDYN("dyn5a ");
|
||||
DEBG("dyn5a ");
|
||||
|
||||
/* build the decoding tables for literal/length and distance codes */
|
||||
bl = lbits;
|
||||
if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0)
|
||||
{
|
||||
DEBGDYN("dyn5b ");
|
||||
DEBG("dyn5b ");
|
||||
if (i == 1) {
|
||||
error(" incomplete literal tree\n");
|
||||
huft_free(tl);
|
||||
}
|
||||
return i; /* incomplete code set */
|
||||
}
|
||||
DEBGDYN("dyn5c ");
|
||||
DEBG("dyn5c ");
|
||||
bd = dbits;
|
||||
if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0)
|
||||
{
|
||||
DEBGDYN("dyn5d ");
|
||||
DEBG("dyn5d ");
|
||||
if (i == 1) {
|
||||
error(" incomplete distance tree\n");
|
||||
#ifdef PKZIP_BUG_WORKAROUND
|
||||
|
|
@ -922,15 +893,13 @@ DEBGDYN("dyn5d ");
|
|||
#endif
|
||||
}
|
||||
|
||||
DEBGDYN("dyn6 free_mem_ptr ");DEBGINT(free_mem_ptr);
|
||||
DEBG("dyn6 ");
|
||||
|
||||
/* decompress until an end-of-block code */
|
||||
DEBG("inflate_codes inptr is "); DEBGINT(inptr);
|
||||
if (inflate_codes(tl, td, bl, bd))
|
||||
return 1;
|
||||
|
||||
DEBG("AFTER inflate_codes inptr is "); DEBGINT(inptr);
|
||||
DEBGDYN("dyn7 ");
|
||||
DEBG("dyn7 ");
|
||||
|
||||
/* free the decoding tables, return */
|
||||
huft_free(tl);
|
||||
|
|
@ -942,18 +911,16 @@ DEBGDYN("dyn7 ");
|
|||
|
||||
|
||||
|
||||
STATIC int inflate_block(
|
||||
int *e) /* last block flag */
|
||||
STATIC int inflate_block(e)
|
||||
int *e; /* last block flag */
|
||||
/* decompress an inflated block */
|
||||
{
|
||||
unsigned t; /* block type */
|
||||
register ulg b; /* bit buffer */
|
||||
register unsigned k; /* number of bits in bit buffer */
|
||||
|
||||
DEBG("<blk(");
|
||||
DEBGINT(inptr);
|
||||
DEBG(")");
|
||||
|
||||
DEBG("<blk");
|
||||
|
||||
/* make local bit buffer */
|
||||
b = bb;
|
||||
k = bk;
|
||||
|
|
@ -991,13 +958,13 @@ int *e) /* last block flag */
|
|||
|
||||
|
||||
|
||||
STATIC int inflate(void)
|
||||
STATIC int inflate()
|
||||
/* decompress an inflated entry */
|
||||
{
|
||||
int e; /* last block flag */
|
||||
int r; /* result code */
|
||||
unsigned h; /* maximum struct huft's malloc'ed */
|
||||
void *ptr;
|
||||
malloc_mark_t mark;
|
||||
|
||||
/* initialize window, bit buffer */
|
||||
wp = 0;
|
||||
|
|
@ -1009,12 +976,12 @@ STATIC int inflate(void)
|
|||
h = 0;
|
||||
do {
|
||||
hufts = 0;
|
||||
gzip_mark(&ptr);
|
||||
malloc_mark(&mark);
|
||||
if ((r = inflate_block(&e)) != 0) {
|
||||
gzip_release(&ptr);
|
||||
malloc_release(&mark);
|
||||
return r;
|
||||
}
|
||||
gzip_release(&ptr);
|
||||
malloc_release(&mark);
|
||||
if (hufts > h)
|
||||
h = hufts;
|
||||
} while (!e);
|
||||
|
|
@ -1043,9 +1010,7 @@ STATIC int inflate(void)
|
|||
**********************************************************************/
|
||||
|
||||
static ulg crc_32_tab[256];
|
||||
/* note that this fails for NVRAM! */
|
||||
/* do assign below in makecrc */
|
||||
static ulg crc ; /*= (ulg)0xffffffffL; shift register contents */
|
||||
static ulg crc; /* initialized in makecrc() so it'll reside in bss */
|
||||
#define CRC_VALUE (crc ^ 0xffffffffL)
|
||||
|
||||
/*
|
||||
|
|
@ -1064,12 +1029,8 @@ makecrc(void)
|
|||
int k; /* byte being shifted into crc apparatus */
|
||||
|
||||
/* terms of polynomial defining this crc (except x^32): */
|
||||
const int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
|
||||
static const int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
|
||||
|
||||
/* move init of the lbits and dbits here, I know this is hokey -- rgm */
|
||||
lbits = 9; /* bits in base literal/length lookup table */
|
||||
dbits = 6; /* bits in base distance lookup table */
|
||||
crc = (ulg)0xffffffffL; /* shift register contents */
|
||||
/* Make exclusive-or pattern from polynomial */
|
||||
e = 0;
|
||||
for (i = 0; i < sizeof(p)/sizeof(int); i++)
|
||||
|
|
@ -1088,6 +1049,9 @@ makecrc(void)
|
|||
}
|
||||
crc_32_tab[i] = c;
|
||||
}
|
||||
|
||||
/* this is initialized here so this code could reside in ROM */
|
||||
crc = (ulg)0xffffffffL; /* shift register contents */
|
||||
}
|
||||
|
||||
/* gzip flag byte */
|
||||
|
|
@ -1102,7 +1066,7 @@ makecrc(void)
|
|||
/*
|
||||
* Do the uncompression!
|
||||
*/
|
||||
static int gunzip(void)
|
||||
int gunzip(void)
|
||||
{
|
||||
uch flags;
|
||||
unsigned char magic[2]; /* magic header */
|
||||
|
|
|
|||
52
src/lib/malloc.c
Normal file
52
src/lib/malloc.c
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
#include <stdlib.h>
|
||||
#include <printk.h>
|
||||
#include <subr.h>
|
||||
|
||||
#if 1
|
||||
#define MALLOCDBG(x)
|
||||
#else
|
||||
#define MALLOCDBG(x) printk x
|
||||
#endif
|
||||
extern unsigned char _heap, _eheap;
|
||||
static size_t free_mem_ptr = (size_t)&_heap; /* Start of heap */
|
||||
static size_t free_mem_end_ptr = (size_t)&_eheap; /* End of heap */
|
||||
|
||||
|
||||
void malloc_mark(malloc_mark_t *place)
|
||||
{
|
||||
*place = free_mem_ptr;
|
||||
DBG("malloc_mark 0x%08lx\n", (unsigned long)free_mem_ptr);
|
||||
}
|
||||
|
||||
void malloc_release(malloc_mark_t *ptr)
|
||||
{
|
||||
free_mem_ptr = *ptr;
|
||||
DBG("malloc_release 0x%08lx\n", (unsigned long)free_mem_ptr);
|
||||
}
|
||||
|
||||
void *malloc(size_t size)
|
||||
{
|
||||
void *p;
|
||||
|
||||
if (size < 0)
|
||||
error("Error! malloc: Size < 0");
|
||||
if (free_mem_ptr <= 0)
|
||||
error("Error! malloc: Free_mem_ptr <= 0");
|
||||
|
||||
free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
|
||||
|
||||
p = (void *) free_mem_ptr;
|
||||
free_mem_ptr += size;
|
||||
|
||||
if (free_mem_ptr >= free_mem_end_ptr)
|
||||
error("Error! malloc: Free_mem_ptr >= free_mem_end_ptr");
|
||||
|
||||
MALLOCDBG(("malloc 0x%08lx\n", (unsigned long)p));
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void free(void *where)
|
||||
{
|
||||
/* Don't care */
|
||||
}
|
||||
56
src/mainboard/intel/l440gx/Config
Normal file
56
src/mainboard/intel/l440gx/Config
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
northbridge intel/440gx
|
||||
southbridge intel/piix4e
|
||||
|
||||
superio NSC/pc87309
|
||||
|
||||
option ENABLE_FIXED_AND_VARIABLE_MTRRS
|
||||
option PIIX4_DEVFN=0x90
|
||||
option NO_KEYBOARD
|
||||
option ZKERNEL_START=0xfff40000
|
||||
option ZKERNEL_MASK=0x3ed
|
||||
option L440GX
|
||||
option SMP
|
||||
|
||||
object mainboard.o
|
||||
|
||||
cpu p6
|
||||
cpu p5
|
||||
|
||||
makerule phlash_floppy: phlash ; mcopy -o /tmp/$(PHLASH_BASE_NAME).bi? a:
|
||||
|
||||
makerule phlash: $(BOOT_IMAGE) linuxbios.rom headers ; rm -f xa?
|
||||
addaction phlash split -b 64k $(BOOT_IMAGE)
|
||||
addaction phlash # Now just touch them if we have a really
|
||||
addaction phlash # small kernel!
|
||||
addaction phlash touch xaa xab xac xad xae xaf xag xah
|
||||
addaction phlash # this is starting at bank 4, and proceeding on. Unused banks are dups
|
||||
addaction phlash # the nvram is odd, all of the banks are interleaved
|
||||
addaction phlash cat $(PHLASH_BASE_NAME).bi1.header xaa > $(PHLASH_BASE_NAME).bi1 #4
|
||||
addaction phlash cat $(PHLASH_BASE_NAME).bi3.header xab > $(PHLASH_BASE_NAME).bi3 #6
|
||||
addaction phlash cat $(PHLASH_BASE_NAME).bi2.header xac > $(PHLASH_BASE_NAME).bi2 #7
|
||||
addaction phlash cat $(PHLASH_BASE_NAME).bi4.header xad > $(PHLASH_BASE_NAME).bi4 #9
|
||||
addaction phlash cat $(PHLASH_BASE_NAME).bi7.header xae > $(PHLASH_BASE_NAME).bi7 #a
|
||||
addaction phlash cat $(PHLASH_BASE_NAME).bi6.header xaf > $(PHLASH_BASE_NAME).bi6 #b
|
||||
addaction phlash cat $(PHLASH_BASE_NAME).bi9.header xag > $(PHLASH_BASE_NAME).bi9 #c
|
||||
addaction phlash cat $(PHLASH_BASE_NAME).bi8.header xah > $(PHLASH_BASE_NAME).bi8 #d
|
||||
addaction phlash cat $(PHLASH_BASE_NAME).bia.header linuxbios.rom > $(PHLASH_BASE_NAME).bia
|
||||
addaction phlash # Part o & 5 seem not to be written reliably for some reason...
|
||||
addaction phlash cat $(PHLASH_BASE_NAME).bio.header /dev/null > $(PHLASH_BASE_NAME).bio
|
||||
addaction phlash cat $(PHLASH_BASE_NAME).bi5.header /dev/null > $(PHLASH_BASE_NAME).bi5
|
||||
addaction phlash sh -x $(TOP)/src/mainboard/intel/l440gx/BUILD_PHLASH_FILES $(PHLASH_BASE_NAME)
|
||||
|
||||
makerule headers : $(PHLASH_BASE_NAME).bi1.header $(PHLASH_BASE_NAME).bi2.header $(PHLASH_BASE_NAME).bi3.header $(PHLASH_BASE_NAME).bi4.header $(PHLASH_BASE_NAME).bi5.header $(PHLASH_BASE_NAME).bi6.header $(PHLASH_BASE_NAME).bi7.header $(PHLASH_BASE_NAME).bi8.header $(PHLASH_BASE_NAME).bi9.header $(PHLASH_BASE_NAME).bia.header $(PHLASH_BASE_NAME).bio.header ;
|
||||
|
||||
makerule $(PHLASH_BASE_NAME).bi1.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bi1 ; dd if=$< of=$@ bs=1 count=160
|
||||
makerule $(PHLASH_BASE_NAME).bi2.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bi2 ; dd if=$< of=$@ bs=1 count=160
|
||||
makerule $(PHLASH_BASE_NAME).bi3.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bi3 ; dd if=$< of=$@ bs=1 count=160
|
||||
makerule $(PHLASH_BASE_NAME).bi4.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bi4 ; dd if=$< of=$@ bs=1 count=160
|
||||
makerule $(PHLASH_BASE_NAME).bi5.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bi5 ; dd if=$< of=$@ bs=1 count=160
|
||||
makerule $(PHLASH_BASE_NAME).bi6.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bi6 ; dd if=$< of=$@ bs=1 count=160
|
||||
makerule $(PHLASH_BASE_NAME).bi7.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bi7 ; dd if=$< of=$@ bs=1 count=160
|
||||
makerule $(PHLASH_BASE_NAME).bi8.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bi8 ; dd if=$< of=$@ bs=1 count=160
|
||||
makerule $(PHLASH_BASE_NAME).bi9.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bi9 ; dd if=$< of=$@ bs=1 count=160
|
||||
makerule $(PHLASH_BASE_NAME).bia.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bia ; dd if=$< of=$@ bs=1 count=160
|
||||
makerule $(PHLASH_BASE_NAME).bio.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bio ; dd if=$< of=$@ bs=1 count=160
|
||||
|
||||
addaction clean rm -f $(PHLASH_BASE_NAME)* xa?
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#include <pc80/i8259.inc>
|
||||
|
||||
#include <superio/NSC/pc87309/superio.inc>
|
||||
#include <superio/NSC/pc87309/setup_serial.inc>
|
||||
|
||||
#include <pc80/serial.inc>
|
||||
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ void mainboard_fixup()
|
|||
#endif
|
||||
#if 1
|
||||
{
|
||||
unsigned char byte;
|
||||
unsigned short word;
|
||||
unsigned long dword;
|
||||
u8 byte;
|
||||
u16 word;
|
||||
u32 dword;
|
||||
for(i = 0; i < 8; i++) {
|
||||
pci_read_config_byte(host_bridge_pcidev, 0x60 +i, &byte);
|
||||
printk("DRB[i] = 0x%02x\n", byte);
|
||||
|
|
|
|||
3
src/northbridge/alpha/tsunami/Config
Normal file
3
src/northbridge/alpha/tsunami/Config
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
cpu ev6
|
||||
option USE_CPU_EV6=1
|
||||
option USE_CORE_TSUNAMI=1
|
||||
4
src/northbridge/intel/440gx/Config
Normal file
4
src/northbridge/intel/440gx/Config
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
raminit northbridge/intel/440gx/raminit.inc
|
||||
raminit sdram/generic_sdram.inc
|
||||
|
||||
object northbridge.o
|
||||
4
src/rom/Config
Normal file
4
src/rom/Config
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
object fill_inbuf.o
|
||||
object rom_fill_inbuf.o
|
||||
object docmil_fill_inbuf.o
|
||||
object tsunami_tigbus_rom_fill_inbuf.o
|
||||
120
src/rom/docmil_fill_inbuf.c
Normal file
120
src/rom/docmil_fill_inbuf.c
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
#ifdef USE_DOC_MIL
|
||||
|
||||
#include <cpu/p5/io.h>
|
||||
#include <printk.h>
|
||||
#include <stdlib.h>
|
||||
#include <subr.h>
|
||||
#include <stddef.h>
|
||||
#include <rom/fill_inbuf.h>
|
||||
|
||||
#ifndef DOC_KERNEL_START
|
||||
#define DOC_KERNEL_START 65536
|
||||
#endif
|
||||
|
||||
static unsigned char *nvram;
|
||||
static int block_count;
|
||||
static int firstfill = 1;
|
||||
|
||||
void memcpy_from_doc_mil(void *dest, const void *src, size_t n);
|
||||
unsigned char *doc_mil = (unsigned char *) 0xffffe000;
|
||||
#ifdef CHECK_DOC_MIL
|
||||
unsigned char *checkbuf;
|
||||
#endif /* CHECK_DOC_MIL */
|
||||
|
||||
static unsigned char *ram;
|
||||
#define K64 (64 * 1024)
|
||||
|
||||
|
||||
int fill_inbuf(void)
|
||||
{
|
||||
if (firstfill) {
|
||||
if ((ram = malloc(K64)) == NULL) {
|
||||
printk(KERN_EMERG "%6d:%s() - ram malloc failed\n",
|
||||
__LINE__, __FUNCTION__);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef CHECK_DOC_MIL
|
||||
if ((checkbuf = malloc(K64)) == NULL) {
|
||||
printk(KERN_EMERG "%6d:%s() - checkbuf malloc failed\n",
|
||||
__LINE__, __FUNCTION__);
|
||||
printk(KERN_EMERG "Checking disabled\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
DBG("%6d:%s() - ram buffer:0x%p\n",
|
||||
__LINE__, __FUNCTION__, ram);
|
||||
|
||||
block_count = 0;
|
||||
firstfill = 0;
|
||||
nvram = (unsigned char *) DOC_KERNEL_START;
|
||||
}
|
||||
|
||||
memcpy_from_doc_mil(ram, nvram, K64);
|
||||
#ifdef CHECK_DOC_MIL
|
||||
if (checkbuf) {
|
||||
memcpy_from_doc_mil(checkbuf, nvram, K64);
|
||||
if (memcmp(checkbuf, ram, K64)) {
|
||||
printk("CHECKBUF FAILS for doc mil!\n");
|
||||
printk(KERN_EMERG "address 0x%x\n", nvram);
|
||||
}
|
||||
}
|
||||
{
|
||||
int i;
|
||||
printk(KERN_INFO "First 16 bytes of block: ");
|
||||
for(i = 0; i < 16; i++)
|
||||
printk("0x%x ", ram[i]);
|
||||
printk(KERN_INFO "\n");
|
||||
}
|
||||
#endif
|
||||
DBG("%6d:%s() - nvram:0x%p block_count:%d\n",
|
||||
__LINE__, __FUNCTION__, nvram, block_count);
|
||||
|
||||
nvram += K64;
|
||||
inbuf = ram;
|
||||
insize = K64;
|
||||
inptr = 1;
|
||||
|
||||
post_code(0xd0 + block_count);
|
||||
block_count++;
|
||||
return inbuf[0];
|
||||
}
|
||||
|
||||
void memcpy_from_doc_mil(void *dest, const void *src, size_t n)
|
||||
{
|
||||
int i;
|
||||
unsigned long address = (unsigned long) src;
|
||||
|
||||
for (i = n; i >= 0; i -= 0x200) {
|
||||
unsigned short c = 0x1000;
|
||||
volatile unsigned char dummy;
|
||||
|
||||
/* issue Read00 flash command */
|
||||
*(unsigned char *) (doc_mil + 0x1004) = 0x03;
|
||||
*(unsigned char *) (doc_mil + 0x800) = 0x00;
|
||||
*(unsigned char *) (doc_mil + 0x101e) = 0x00;
|
||||
*(unsigned char *) (doc_mil + 0x1004) = 0x01;
|
||||
|
||||
/* issue Address to flash */
|
||||
*(unsigned char *) (doc_mil + 0x1004) = 0x05;
|
||||
*(unsigned char *) (doc_mil + 0x800) = address & 0xff;
|
||||
*(unsigned char *) (doc_mil + 0x800) = (address >> 9) & 0xff;
|
||||
*(unsigned char *) (doc_mil + 0x800) = (address >> 17) & 0xff;
|
||||
*(unsigned char *) (doc_mil + 0x101e) = 0x00;
|
||||
*(unsigned char *) (doc_mil + 0x1004) = 0x01;
|
||||
|
||||
/* We are using the "side effect" of the assignment to force GCC reload
|
||||
* *(doc_mil + 0x1004) on each iteration */
|
||||
while (!((dummy = *(unsigned char *) (doc_mil + 0x1004)) & 0x80) && --c)
|
||||
/* wait for chip response */;
|
||||
|
||||
/* copy 512 bytes of data from CDSN_IO registers */
|
||||
dummy = *(unsigned char *) (doc_mil + 0x101d);
|
||||
memcpy(dest, doc_mil + 0x800, 0x200);
|
||||
|
||||
dest += 0x200;
|
||||
address += 0x200;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USE_DOC_MIL */
|
||||
7
src/rom/fill_inbuf.c
Normal file
7
src/rom/fill_inbuf.c
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#include <rom/fill_inbuf.h>
|
||||
|
||||
unsigned char *inbuf /* = 0 */;
|
||||
unsigned int insize /* = 0 */;
|
||||
unsigned int inptr /* = 0 */;
|
||||
|
||||
|
||||
117
src/rom/rom_fill_inbuf.c
Normal file
117
src/rom/rom_fill_inbuf.c
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
#ifdef USE_GENERIC_ROM
|
||||
|
||||
#include <printk.h>
|
||||
#include <stdlib.h>
|
||||
#include <subr.h>
|
||||
#include <stddef.h>
|
||||
#include <rom/fill_inbuf.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifndef ZKERNEL_START
|
||||
#define ZKERNEL_START 0xfff80000
|
||||
#endif
|
||||
|
||||
#ifndef ZKERNEL_MASK
|
||||
#define ZKERNEL_MASK 0x0000ffff
|
||||
#endif
|
||||
|
||||
static unsigned char *zkernel_start = (unsigned char *)ZKERNEL_START;
|
||||
static unsigned long zkernel_mask = ZKERNEL_MASK;
|
||||
|
||||
static unsigned char *nvram;
|
||||
static int block_count;
|
||||
static int firstfill = 1;
|
||||
|
||||
#if defined(INBUF_COPY)
|
||||
static unsigned char *ram;
|
||||
#endif
|
||||
|
||||
#define K64 (64 * 1024)
|
||||
|
||||
int fill_inbuf(void)
|
||||
{
|
||||
extern unsigned char *inbuf;
|
||||
extern unsigned int insize;
|
||||
extern unsigned int inptr;
|
||||
|
||||
if (firstfill) {
|
||||
block_count = 0;
|
||||
firstfill = 0;
|
||||
#ifdef INBUF_COPY
|
||||
ram = malloc(K64);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (block_count > 31) {
|
||||
printk(KERN_EMERG "%6d:%s() - overflowed source buffer\n",
|
||||
__LINE__, __FUNCTION__);
|
||||
inbuf = zkernel_start;
|
||||
inptr = 0;
|
||||
insize = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (!block_count) {
|
||||
nvram = zkernel_start;
|
||||
|
||||
#ifdef INBUF_COPY
|
||||
if (!ram) {
|
||||
printk(KERN_EMERG "%6d:%s() - "
|
||||
"ram malloc failed\n",
|
||||
__LINE__, __FUNCTION__);
|
||||
inbuf = zkernel_start;
|
||||
inptr = 0;
|
||||
insize = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
DBG("%6d:%s() - ram buffer:0x%08x\n",
|
||||
__LINE__, __FUNCTION__, ram);
|
||||
#endif
|
||||
DBG("%6d:%s() - zkernel_start:0x%08x "
|
||||
"zkernel_mask:0x%08x\n",
|
||||
__LINE__, __FUNCTION__,
|
||||
zkernel_start, zkernel_mask);
|
||||
} else {
|
||||
nvram += K64;
|
||||
|
||||
while (!(zkernel_mask & (1 << block_count))) {
|
||||
DBG("%6d:%s() - skipping block %d\n",
|
||||
__LINE__, __FUNCTION__, block_count);
|
||||
|
||||
block_count++;
|
||||
nvram += K64;
|
||||
|
||||
if (block_count > 31) {
|
||||
printk(KERN_EMERG "%6d:%s() - "
|
||||
"overflowed source buffer\n",
|
||||
__LINE__, __FUNCTION__);
|
||||
inbuf = zkernel_start;
|
||||
inptr = 0;
|
||||
insize = 1;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef INBUF_COPY
|
||||
memcpy(ram, nvram, K64);
|
||||
#endif
|
||||
DBG("%6d:%s() - nvram:0x%p block_count:%d\n",
|
||||
__LINE__, __FUNCTION__, nvram, block_count);
|
||||
|
||||
#ifdef INBUF_COPY
|
||||
inbuf = ram;
|
||||
#else
|
||||
inbuf = nvram;
|
||||
#endif
|
||||
insize = K64;
|
||||
inptr = 1;
|
||||
post_code(0xd0 + block_count);
|
||||
block_count++;
|
||||
return inbuf[0];
|
||||
}
|
||||
|
||||
|
||||
#endif /* USE_GENERIC_ROM */
|
||||
98
src/rom/tsunami_tigbus_rom_fill_inbuf.c
Normal file
98
src/rom/tsunami_tigbus_rom_fill_inbuf.c
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
#ifdef USE_TSUNAMI_TIGBUS_ROM
|
||||
|
||||
#include <printk.h>
|
||||
#include <stdlib.h>
|
||||
#include <subr.h>
|
||||
#include <stddef.h>
|
||||
#include <rom/fill_inbuf.h>
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <northbridge/alpha/tsunami/core_tsunami.h>
|
||||
|
||||
#ifndef TIG_KERNEL_START
|
||||
#define TIG_KERNEL_START 0x20000
|
||||
#endif
|
||||
|
||||
static unsigned long nvram;
|
||||
static int block_count;
|
||||
static int firstfill = 1;
|
||||
static unsigned char *ram;
|
||||
|
||||
#define K64 (64 * 1024)
|
||||
|
||||
#define MAX_TIG_FLASH_SIZE (16*1024*1024)
|
||||
static void tsunami_flash_copy_from(void *addr, unsigned long offset, long len)
|
||||
{
|
||||
|
||||
unsigned char *dest;
|
||||
dest = addr;
|
||||
while(len && (offset < MAX_TIG_FLASH_SIZE)) {
|
||||
*dest = tsunami_tig_readb(offset);
|
||||
offset++;
|
||||
dest++;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
|
||||
int fill_inbuf(void)
|
||||
{
|
||||
extern unsigned char *inbuf;
|
||||
extern unsigned int insize;
|
||||
extern unsigned int inptr;
|
||||
|
||||
if (firstfill) {
|
||||
block_count = 0;
|
||||
firstfill = 0;
|
||||
ram = malloc(K64);
|
||||
if (!ram) {
|
||||
printk(KERN_EMERG "%6d:%s() - "
|
||||
"ram malloc failed\n",
|
||||
__LINE__, __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (block_count > 31) {
|
||||
printk(KERN_EMERG "%6d:%s() - overflowed source buffer\n",
|
||||
__LINE__, __FUNCTION__);
|
||||
insize = 0;
|
||||
return (0);
|
||||
}
|
||||
if (!block_count) {
|
||||
nvram = TIG_KERNEL_START;
|
||||
DBG("%6d:%s() - ram buffer:0x%08x\n",
|
||||
__LINE__, __FUNCTION__, ram);
|
||||
DBG("%6d:%s() - TIG_KERNEL_START:0x%08x\n",
|
||||
__LINE__, __FUNCTION__,
|
||||
TIG_KERNEL_START);
|
||||
}
|
||||
|
||||
|
||||
tsunami_flash_copy_from(ram, nvram, K64);
|
||||
DBG("\n%6d:%s() - nvram:0x%lx block_count:%d\n",
|
||||
__LINE__, __FUNCTION__, nvram, block_count);
|
||||
|
||||
#if 0
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < K64; i+= 16) {
|
||||
printk("%05x: %02x %02x %02x %02x %02x %02x %02x %02x "
|
||||
"%02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
(block_count << 16)+i,
|
||||
ram[i+0], ram[i+1], ram[i+2], ram[i+3],
|
||||
ram[i+4], ram[i+5], ram[i+6], ram[i+7],
|
||||
ram[i+8], ram[i+9], ram[i+10], ram[i+11],
|
||||
ram[i+12], ram[i+13], ram[i+14],ram[i+15]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
nvram += K64;
|
||||
inbuf = ram;
|
||||
insize = K64;
|
||||
inptr = 1;
|
||||
post_code(0xd0 + block_count);
|
||||
block_count++;
|
||||
return inbuf[0];
|
||||
}
|
||||
|
||||
#endif /* USE_TSUNAMI_TIGBUS_ROM */
|
||||
47
src/superio/NSC/pc87309/setup_serial.inc
Normal file
47
src/superio/NSC/pc87309/setup_serial.inc
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Enable the peripheral devices on the NSC Super IO chip PC87309
|
||||
* For now this is specific to the L440GX motherboard.
|
||||
*/
|
||||
|
||||
|
||||
/* The base address is 0x15c, 0x2e, depending on config bytes */
|
||||
|
||||
#define SIO_BASE $0x2e
|
||||
#define SIO_INDEX SIO_BASE
|
||||
#define SIO_DATA SIO_BASE+1
|
||||
|
||||
#define SIO_READ(ldn, index) \
|
||||
mov SIO_BASE, %dx ; \
|
||||
mov $0x07, %al ; \
|
||||
outb %al, %dx ; \
|
||||
inc %dx ; \
|
||||
mov ldn, %al ; \
|
||||
outb %al, %dx ; \
|
||||
dec %dx ; \
|
||||
mov index, %al ; \
|
||||
outb %al, %dx ; \
|
||||
inc %dx ; \
|
||||
inb %dx, %al ;
|
||||
|
||||
#define SIO_WRITE(ldn, index, data) \
|
||||
mov SIO_BASE, %dx ; \
|
||||
mov $0x07, %al ; \
|
||||
outb %al, %dx ; \
|
||||
inc %dx ; \
|
||||
mov ldn, %al ; \
|
||||
outb %al, %dx ; \
|
||||
dec %dx ; \
|
||||
mov index, %al ; \
|
||||
outb %al, %dx ; \
|
||||
inc %dx ; \
|
||||
mov data, %al ; \
|
||||
outb %al, %dx ;
|
||||
|
||||
|
||||
/* At boot up the chip is in configure mode so don't worry
|
||||
* about getting it there just configure some peripherals.
|
||||
*/
|
||||
|
||||
/* enable serial 1 */
|
||||
SIO_WRITE($0x03, $0x30, $0x01)
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue