Lots and Lots of changes. Mainly bugfixes for the supermicro p4dc6,

and a bunch of generic changes.
- Started playing with automatic scanning memory for LinuxBIOS tables.
- Converted the fill_inbuf drivers to stream drivers.  This allows
  for pure data copying operations to be faster, and it allows skipping
  of unneeded data on platforms that support it.
- Added a section .rodata.streams for the stream driver control structures.
  This is preparation for building a bootloader that shares source code
  with LinuxBIOS.
- Added a driver command to NLBConfig.py for objects that should
  always be linked into LinuxBIOS if they are compiled at all.
- Moved the boot_successful logic down into the guts of the
  bootloaders.
- Modified the ip style checksum logic so it isn't specific to uniform
  boot headers...
- Added a function ndelay that uses the RTC (this is i786 specific for now).
- Added a function to delay in seconds for the braindead harddrive
  spinup logic.
- Added a floppy stream driver.
- Added a ide stream driver.
- Broke out the ram initialization for the p4dc6 into multiple c files.
- Stupidly adapted linuxbiosmain and do_inflate to the new stream
  interface.  get_byte is now a slow function call so it might be able
  to use some optimization.
- Updated the ELF bootloader to the new stream interface and adding a
  ELF header scanning function so we can boot off of harddrives and
  not smash their partition tables.
- Removed some bogus unlook ahead code from inflate.c
- Fixed a problem where we did not enable I/O resources on VGA
  compatible chips.  This caused a trident card to lock up the system
  when it's memory mapped resources were enabled.
- Correctly set up nested pci busses.  Before this a pci bus behind a
  pci bus would not get enabled.
- Config changes to the p4dc6
- Added more interrupt sources to the p4dc6 interrupt table
- Converted all of the inbuf drivers to stream drivers.
  All have good conversions except the doc_millenium.
This commit is contained in:
Eric W. Biederman 2001-12-20 04:04:42 +00:00
commit cb232f1e04
38 changed files with 3386 additions and 283 deletions

View file

@ -1,7 +1,9 @@
object fill_inbuf.o
object rom_fill_inbuf.o
object docmil_fill_inbuf.o
#object docplus_fill_inbuf.o
object tsunami_tigbus_rom_fill_inbuf.o
object serial_fill_inbuf.o
object tftp_fill_inbuf.o
driver rom_fill_inbuf.o USE_GENERIC_ROM
driver docmil_fill_inbuf.o
#driver docplus_fill_inbuf.o
driver tsunami_tigbus_rom_fill_inbuf.o USE_TSUNAMI_TIGBUS_ROM
driver serial_fill_inbuf.o USE_SERIAL_FILL_INBUF
driver tftp_fill_inbuf.o USE_TFTP
driver floppy_fill_inbuf.o BOOT_FLOPPY
driver ide_fill_inbuf.o BOOT_IDE
#object read_bytes.o

View file

@ -20,6 +20,10 @@
#define DOC_MIL_BASE 0xffffe000
#endif
static unsigned char *inbuf; /* input buffer */
static unsigned int insize; /* valid bytes in inbuf */
static unsigned int inptr; /* index of next byte to be processed in inbuf */
static unsigned char *nvram;
static int block_count;
static int firstfill = 1;
@ -53,7 +57,7 @@ reset_doc()
}
#endif
int
static int
fill_inbuf(void)
{
#ifdef CHECK_DOC_MIL
@ -373,7 +377,7 @@ static int DoCMil_is_alias(volatile char *docptr1, volatile char *docptr2)
}
#if 0
int WriteBlockECC(volatile char *docptr, unsigned int block, const char *buf)
static int WriteBlockECC(volatile char *docptr, unsigned int block, const char *buf)
{
unsigned char eccbuf[6];
volatile char dummy;
@ -458,7 +462,7 @@ int WriteBlockECC(volatile char *docptr, unsigned int block, const char *buf)
}
#endif
int ReadBlockECC( volatile unsigned char *docptr, unsigned int block, char *buf)
static int ReadBlockECC( volatile unsigned char *docptr, unsigned int block, char *buf)
{
int i, ret;
volatile char dummy;
@ -591,4 +595,46 @@ memcpy_from_doc_mil(void *dest, const void *src, size_t n)
}
}
/* FIXME this is a very lazy ugly port of the new interface to the doc millenium
* find a good way to implement this...
*/
#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
static int init_bytes(void)
{
return;
}
static void fini_bytes(void)
{
return;
}
static byte_offset_t read_bytes(void *vdest, byte_offset_t count)
{
byte_offset_t bytes = 0;
unsigned char *dest = vdest;
while(bytes < count) {
*(dest++) = get_byte();
}
return count;
}
static byte_offset_t skip_bytes(byte_offset_t count)
{
byte_offset_t bytes = 0;
while(bytes < count) {
unsigned char byte;
byte = get_byte();
}
return count;
}
static struct stream doc_mil_stream __stream = {
.init = init_bytes,
.read = read_bytes,
.skip = skip_bytes,
.fini = fini_bytes,
}
#endif /* USE_DOC_MIL */

View file

@ -0,0 +1,44 @@
#include <printk.h>
#include <stdlib.h>
#include <subr.h>
#include <stddef.h>
#include <rom/read_bytes.h>
#include <string.h>
#include <floppy_subr.h>
static unsigned long offset;
static int init_bytes(void)
{
offset = 0;
return floppy_init();
}
static void fini_bytes(void)
{
floppy_fini();
}
static byte_offset_t read_bytes(void *vdest, byte_offset_t count)
{
byte_offset_t len;
len = floppy_read(vdest, offset, count);
if (len > 0) {
offset += len;
}
return len;
}
static byte_offset_t skip_bytes(byte_offset_t count)
{
offset += count;
return count;
}
static struct stream floppy_bytes __stream = {
.init = init_bytes,
.read = read_bytes,
.skip = skip_bytes,
.fini = fini_bytes,
};

84
src/rom/ide_fill_inbuf.c Normal file
View file

@ -0,0 +1,84 @@
#include <printk.h>
#include <stdlib.h>
#include <subr.h>
#include <stddef.h>
#include <rom/read_bytes.h>
#include <delay.h>
#include <string.h>
#include <floppy_subr.h>
/* read a sector or a partial sector */
extern int ide_read_sector(int drive, void * buffer, unsigned int block, int byte_offset,
int n_bytes);
extern int ide_init(void);
static unsigned long offset;
static int init_bytes(void)
{
int i;
printk_debug ("Trying polled ide\n");
printk_debug ("Waiting for ide disks to spin up\n");
printk_debug ("This is a hard coded delay and longer than necessary.\n");
for(i = 0; i < 25; i++) {
printk_debug(".");
delay(1);
}
printk_debug("\n");
offset = 0;
return ide_init();
}
static void fini_bytes(void)
{
return;
}
static byte_offset_t ide_read(void *vdest, byte_offset_t offset, byte_offset_t count)
{
byte_offset_t bytes = 0;
unsigned char *dest = vdest;
while(bytes < count) {
unsigned int block, byte_offset, len;
int result;
block = offset / 512;
byte_offset = offset %512;
len = 512 - byte_offset;
if (len > (count - bytes)) {
len = (count - bytes);
}
result = ide_read_sector(0, dest, block , byte_offset, len);
if (result != 0) {
return bytes;
}
offset += len;
bytes += len;
dest += len;
}
return bytes;
}
static byte_offset_t read_bytes(void *vdest, byte_offset_t count)
{
byte_offset_t len;
len = ide_read(vdest, offset, count);
if (len > 0) {
offset += len;
}
return len;
}
static byte_offset_t skip_bytes(byte_offset_t count)
{
offset += count;
return count;
}
static struct stream ide_stream __stream = {
.init = init_bytes,
.read = read_bytes,
.skip = skip_bytes,
.fini = fini_bytes,
};

View file

@ -1,10 +1,8 @@
#ifdef USE_GENERIC_ROM
#include <printk.h>
#include <stdlib.h>
#include <subr.h>
#include <stddef.h>
#include <rom/fill_inbuf.h>
#include <rom/read_bytes.h>
#include <string.h>
@ -16,102 +14,85 @@
#define ZKERNEL_MASK 0x0000ffff
#endif
/* The inbuf copy option has been killed... */
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
static int block_offset;
#define K64 (64 * 1024)
int fill_inbuf(void)
static int init_bytes(void)
{
extern unsigned char *inbuf;
extern unsigned int insize;
extern unsigned int inptr;
block_count = 0;
block_offset = 0;
nvram = zkernel_start;
if (firstfill) {
block_count = 0;
firstfill = 0;
#ifdef INBUF_COPY
ram = malloc(K64);
#endif
}
printk_debug("%6d:%s() - zkernel_start:0x%08x "
"zkernel_mask:0x%08x\n",
__LINE__, __FUNCTION__,
zkernel_start, zkernel_mask);
if (block_count > 31) {
printk_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_emerg("%6d:%s() - "
"ram malloc failed\n",
__LINE__, __FUNCTION__);
inbuf = zkernel_start;
inptr = 0;
insize = 0;
return (0);
}
printk_debug("%6d:%s() - ram buffer:0x%08x\n",
__LINE__, __FUNCTION__, ram);
#endif
printk_debug("%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))) {
printk_debug("%6d:%s() - skipping block %d\n",
__LINE__, __FUNCTION__, block_count);
block_count++;
nvram += K64;
if (block_count > 31) {
printk_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
printk_debug("%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];
return 0;
}
#endif /* USE_GENERIC_ROM */
static void fini_bytes(void)
{
return;
}
static byte_offset_t rom_read_bytes(int cp, void *vdest, byte_offset_t count)
{
unsigned char *dest = vdest;
byte_offset_t bytes = 0;
while (bytes < count) {
int length;
if (block_offset == K64) {
block_offset = 0;
block_count++;
nvram+= K64;
}
if (!(zkernel_mask & (1 << block_count))) {
printk_debug("%6d:%s() - skipping block %d\n",
__LINE__, __FUNCTION__, block_count);
continue;
}
if (block_count > 31) {
printk_emerg( "%6d:%s() - overflowed source buffer\n",
__LINE__, __FUNCTION__);
return bytes;
}
length = K64 - block_offset;
if (length > count) {
length = count;
}
if (cp) {
memcpy(dest, nvram + block_offset, length);
}
dest += length;
block_offset += length;
bytes += length;
}
return bytes;
}
static byte_offset_t skip_bytes(byte_offset_t count)
{
return rom_read_bytes(0, 0, count);
}
static byte_offset_t read_bytes(void *vdest, byte_offset_t count)
{
return rom_read_bytes(1, vdest, count);
}
static struct stream rom_stream __stream = {
.init = init_bytes,
.read = read_bytes,
.skip = skip_bytes,
.fini = fini_bytes,
};

View file

@ -1,32 +1,36 @@
#ifdef USE_SERIAL_FILL_INBUF
#include <printk.h>
#include <stdlib.h>
#include <subr.h>
#include <stddef.h>
#include <rom/fill_inbuf.h>
#include <rom/read_bytes.h>
#include <string.h>
#include <serial_subr.h>
static int firstfill = 1;
static unsigned char *ram;
#define K64 (64*1024)
int fill_inbuf(void)
static int init_bytes(void)
{
int rc;
if (firstfill) {
firstfill = 0;
ram = malloc(K64);
return 0;
}
static void fini_bytes(void)
{
}
static byte_offset_t read_bytes(void *vdest, byte_offset_t count)
{
return ttys0_rx_bytes(vdest, count);
}
static byte_offset_t skip_bytes(byte_offset_t count)
{
int64_t i;
for(i = 0; i < count; i++) {
unsigned char byte;
byte = ttys0_rx_byte();
}
inbuf = ram;
insize = ttys0_rx_bytes(inbuf, K64);
inptr = 1;
return inbuf[0];
}
#endif /* USE_SERIAL_FILL_INBUF */
static struct stream serial_stream __stream = {
.init = init_bytes,
.read = read_bytes,
.skip = skip_bytes,
.fini = fini_bytes,
};

View file

@ -1,54 +1,79 @@
#ifdef USE_TFTP
#include <cpu/p5/io.h>
#include <printk.h>
#include <stdlib.h>
#include <subr.h>
#include <stddef.h>
#include <rom/fill_inbuf.h>
#include <rom/read_bytes.h>
#ifndef DOC_KERNEL_START
#define DOC_KERNEL_START 65536
#endif
static int block_bytes;
static int block_offset;
static unsigned char *buffer;
static int keof;
static unsigned char *nvram;
static int block_count;
static int firstfill = 1;
extern int tftp_init(const char *name);
static void memcpy_from_doc_mil(void *dest, const void *src, size_t n);
static unsigned char *doc_mil = (unsigned char *) 0xffffe000;
#ifdef CHECK_DOC_MIL
static unsigned char *checkbuf;
#endif /* CHECK_DOC_MIL */
static unsigned char *ram;
#define K64 (64 * 1024)
int fill_inbuf(void)
static int init_bytes(void)
{
extern unsigned char *inbuf;
extern unsigned int insize;
extern unsigned int inptr;
int rc;
static keof;
if(keof)
return(-1);
if(firstfill) {
tftp_init("vmlinux");
block_count = 0;
firstfill = 0;
inbuf = ram = malloc(512);
keof=0;
tftp_init("vmlinux");
block_bytes = 0;
block_offset = 0;
firstfill = 0;
buffer = malloc(512);
if (buffer == 0) {
return -1;
}
rc = tftp_fetchone(ram);
insize = rc;
inptr = 1;
return inbuf[0];
keof=0;
}
#endif // USE_TFTP
static void fini_bytes(void)
{
free(buffer);
buffer = 0;
}
static byte_offset_t tftp_read_bytes(int cp, void *vdest, byte_offset_t count)
{
byte_offset_t bytes = 0;
unsigned char *dest = vdest;
if (keof)
return -1;
do {
int length;
if (block_bytes - block_offset == 0) {
block_offset = 0;
block_bytes = tftp_fetchone(buffer);
}
if (block_bytes <= 0) {
keof = 1;
return -1;
}
length = block_bytes - block_offset;
if (length > count) {
length = count;
}
if (cp) {
memcpy(dest, buffer, + block_offset, length);
}
block_offset += length;
dest += length;
} while (bytes < count);
return bytes;
}
static byte_offset_t skip_bytes(byte_offset_t count)
{
return tftp_read_bytes(0, 0, count);
}
static byte_offset_t read_bytes(void *vdest, byte_offset_t count)
{
return tftp_read_bytes(1, vdest, count);
}
static struct stream tftp_stream __stream = {
.init = init_bytes,
.read = read_bytes,
.skip = skip_bytes,
.fini = fini_bytes,
};

View file

@ -1,10 +1,8 @@
#ifdef USE_TSUNAMI_TIGBUS_ROM
#include <printk.h>
#include <stdlib.h>
#include <subr.h>
#include <stddef.h>
#include <rom/fill_inbuf.h>
#include <rom/read_bytes.h>
#include <arch/io.h>
#include <northbridge/alpha/tsunami/core_tsunami.h>
@ -13,12 +11,7 @@
#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)
static unsigned long offset;
#define MAX_TIG_FLASH_SIZE (16*1024*1024)
static void tsunami_flash_copy_from(void *addr, unsigned long offset, long len)
@ -34,65 +27,49 @@ static void tsunami_flash_copy_from(void *addr, unsigned long offset, long len)
}
}
int fill_inbuf(void)
static int init_bytes(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_emerg("%6d:%s() - "
"ram malloc failed\n",
__LINE__, __FUNCTION__);
return 0;
}
offset = 0;
printk_debug("%6d:%s() - TIG_KERNEL_START:0x%08x\n",
__LINE__, __FUNCTION__,
TIG_KERNEL_START);
}
static void fini_bytes(void)
{
return;
}
static byte_offset_t skip_bytes(byte_offset_t count)
{
unsigned long new_offset;
byte_offset_t len;
new_offset = offset + count;
if (new_offset > MAX_TIG_FLASH_SIZE) {
new_offset = MAX_TIG_FLASH_SIZE;
}
if (block_count > 31) {
printk_emerg("%6d:%s() - overflowed source buffer\n",
__LINE__, __FUNCTION__);
insize = 0;
return (0);
}
if (!block_count) {
nvram = TIG_KERNEL_START;
printk_debug("%6d:%s() - ram buffer:0x%08x\n",
__LINE__, __FUNCTION__, ram);
printk_debug("%6d:%s() - TIG_KERNEL_START:0x%08x\n",
__LINE__, __FUNCTION__,
TIG_KERNEL_START);
}
tsunami_flash_copy_from(ram, nvram, K64);
printk_debug("\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_debug("%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];
len = new_offset - offset;
offset = new_offset;
return len;
}
#endif /* USE_TSUNAMI_TIGBUS_ROM */
static byte_offset_t read_bytes(void *vdest, byte_offset_t count)
{
long length;
length = MAX_TIG_FLASH_SIZE - offset;
if (count < 0)
count = 0;
if (count < length) {
length = count;
}
tsunami_flash_copy_from(vdest, offset, length);
offset += length;
return length;
}
static struct stream tsunami_tigbus_rom_stream __stream = {
.init = init_bytes,
.read = read_bytes,
.skip = skip_bytes,
.fini = fini_bytes,
};