- update mkelfImageto version 1.16

- cleanup the w83627hf header, and function names
- rename power_led to w83627hf_power_led
- rename w832627hf_power_after_power_fail to w83627hf_power_after_power_fail
- smbus_read_block != smbus_read_byte
- Update build_opt_tble to handle checksum entries
----------------------------------------------------------------------
This commit is contained in:
Eric W. Biederman 2002-10-25 19:26:13 +00:00
parent d0bec9e108
commit ab330196a1
9 changed files with 360 additions and 94 deletions

View file

@ -28,28 +28,23 @@
#define HW_MONITOR_DEVICE 0xb
#define FLOPPY_DEFAULT_IOBASE 0x3f0
#define FLOPPY_DEFAULT_IRQ 6
#define FLOPPY_DEFAULT_DRQ 2
#define PARALLEL_DEFAULT_IOBASE 0x378
#define PARALLEL_DEFAULT_IRQ 7
#define PARALLEL_DEFAULT_DRQ 4 /* No dma */
#define COM1_DEFAULT_IOBASE 0x3f8
#define COM1_DEFAULT_IRQ 4
#define COM1_DEFAULT_BAUD 115200
#define COM2_DEFAULT_IOBASE 0x2f8
#define COM2_DEFAULT_IRQ 3
#define COM2_DEFAULT_BAUD 115200
#define KBC_DEFAULT_IOBASE0 0x60
#define KBC_DEFAULT_IOBASE1 0x64
#define KBC_DEFAULT_IRQ0 0x1
#define KBC_DEFAULT_IRQ1 0xc
#define HW_MONITOR_DEFAULT_IOBASE0 0x295
#define LED_OFF 0x00
#define LED_ON 0x40
#define LED_BLINK_1SEC 0x80
#define LED_BLINK_4SEC 0xC0
#define FLOPPY_DEFAULT_IOBASE 0x3f0
#define FLOPPY_DEFAULT_IRQ 6
#define FLOPPY_DEFAULT_DRQ 2
#define PARALLEL_DEFAULT_IOBASE 0x378
#define PARALLEL_DEFAULT_IRQ 7
#define PARALLEL_DEFAULT_DRQ 4 /* No dma */
#define COM1_DEFAULT_IOBASE 0x3f8
#define COM1_DEFAULT_IRQ 4
#define COM1_DEFAULT_BAUD 115200
#define COM2_DEFAULT_IOBASE 0x2f8
#define COM2_DEFAULT_IRQ 3
#define COM2_DEFAULT_BAUD 115200
#define KBC_DEFAULT_IOBASE0 0x60
#define KBC_DEFAULT_IOBASE1 0x64
#define KBC_DEFAULT_IRQ0 0x1
#define KBC_DEFAULT_IRQ1 0xc
#define HW_MONITOR_DEFAULT_IOBASE0 0x295
#if !defined(ASSEMBLY)
void w83627hf_enter_pnp(unsigned char port);
@ -59,7 +54,14 @@ void w83627hf_exit_pnp(unsigned char port);
#define POWER_ON 1
#define POWER_PREV 2
void w832627hf_power_after_power_fail(int state);
void w83627hf_power_after_power_fail(int state);
#define LED_OFF 0x00
#define LED_ON 0x40
#define LED_BLINK_1SEC 0x80
#define LED_BLINK_4SEC 0xC0
void w83627hf_power_led(int);
#endif
#endif /* SUPERIO_W83627HF_H */

View file

@ -1,29 +1,14 @@
.section ".rom.data"
/*
* Routine: smbus_read_byte
* Arguments: %esp return address
* %bl device on the smbus to read from
* %bh address on the smbus to read
*
* Results: zf clear
* byte read %eax
* On Error:
* zf set
* %eax trashed
*
* Trashed: %edx, %eax
* Effects: reads a byte off of the smbus
*/
#define SMBUS_READ_BYTE(device, address) \
movl $( (device) | ((address) << 8)), %ebx ; \
CALLSP(smbus_read_byte)
smbus_read_byte:
/* smbus read a block of data
input: bl device, bh command, cl count,
esi pointer to data block
output: cf set on error
*/
smbus_read_block:
/* poll until the smbus is ready for commands */
SMBUS_WAIT_UNTIL_READY()
jc smbus_read_byte_failed
jc smbus_block_read_error
/* setup transaction */
/* disable interrupts */
@ -32,7 +17,7 @@ smbus_read_byte:
andb $0xFE, %al
outb %al, %dx
/* set the device I'm talking to */
/* set the device I'm talking to and specify a read */
movl $(SMBUS_IO_BASE + SMBXMITADD), %edx
movb %bl /* device */, %al
shlb $1, %al
@ -44,11 +29,16 @@ smbus_read_byte:
movb %bh /* address */, %al
outb %al, %dx
/* setup for a byte data read */
/* setup for a block data read/write */
movl $(SMBUS_IO_BASE + SMBHSTCTL), %edx
inb %dx, %al
andb $0xE3, %al
orb $(0x2 << 2), %al
orb $(0x5 << 2), %al
outb %al, %dx
/* set the block count */
movl $(SMBUS_IO_BASE + SMBHSTDAT0), %edx
movb %cl /* count */, %al
outb %al, %dx
/* clear any lingering errors, so the transaction will run */
@ -56,36 +46,40 @@ smbus_read_byte:
inb %dx, %al
outb %al, %dx
/* clear the data byte... */
movl $(SMBUS_IO_BASE + SMBHSTDAT0), %edx
xorl %eax, %eax
outb %al, %dx
/* start a byte read, with interrupts disabled */
/* start a block read, with interrupts disabled */
movl $(SMBUS_IO_BASE + SMBHSTCTL), %edx
inb %dx, %al
orb $0x40, %al
orb $(1 << 6), %al
outb %al, %dx
/* poll for transaction completion */
SMBUS_WAIT_UNTIL_DONE()
jc smbus_read_byte_failed
smbus_block_read_next:
/* wait until the controller has more data ready */
SMBUS_WAIT_UNTIL_NEXT()
jc smbus_block_read_error
/* read the results and see if we succeded */
movl $(SMBUS_IO_BASE + SMBHSTSTAT), %edx
inb %dx, %al
andb $~(1 << 6), %al /* Ignore the In Use Status... */
cmpb $0x02, %al
jne smbus_read_byte_failed
/* Test the results to see if we succeeded */
testb $(1<<7), %al
jz smbus_block_read_error
movl $(SMBUS_IO_BASE + SMBHSTDAT0), %edx
testl %edx, %edx /* clear zf */
/* read the next byte */
movl $(SMBUS_IO_BASE + SMBBLKDAT), %edx
inb %dx, %al
smbus_read_byte_done:
stosb %al, (%esi)
/* finish this byte read */
movl $(SMBUS_IO_BASE + SMBHSTSTAT), %edx
movb $(1<<7), %al
outb %al, %dx
decb %cl
jnz smbus_block_read_next
/* No error I am done */
clc
smbus_block_read_end:
RETSP
smbus_read_byte_failed:
smbus_block_read_error:
SMBUS_KILL_COMMAND()
xorl %eax, %eax /* set zf */
jmp smbus_read_byte_done
stc
jmp smbus_block_noop_read_end
.previous

View file

@ -0,0 +1,91 @@
.section ".rom.data"
/*
* Routine: smbus_read_byte
* Arguments: %esp return address
* %bl device on the smbus to read from
* %bh address on the smbus to read
*
* Results: zf clear
* byte read %eax
* On Error:
* zf set
* %eax trashed
*
* Trashed: %edx, %eax
* Effects: reads a byte off of the smbus
*/
#define SMBUS_READ_BYTE(device, address) \
movl $( (device) | ((address) << 8)), %ebx ; \
CALLSP(smbus_read_byte)
smbus_read_byte:
/* poll until the smbus is ready for commands */
SMBUS_WAIT_UNTIL_READY()
jc smbus_read_byte_failed
/* setup transaction */
/* disable interrupts */
movl $(SMBUS_IO_BASE + SMBHSTCTL), %edx
inb %dx, %al
andb $0xFE, %al
outb %al, %dx
/* set the device I'm talking to */
movl $(SMBUS_IO_BASE + SMBXMITADD), %edx
movb %bl /* device */, %al
shlb $1, %al
orb $1, %al
outb %al, %dx
/* set the command address... */
movl $(SMBUS_IO_BASE + SMBHSTCMD), %edx
movb %bh /* address */, %al
outb %al, %dx
/* setup for a byte data read */
movl $(SMBUS_IO_BASE + SMBHSTCTL), %edx
inb %dx, %al
andb $0xE3, %al
orb $(0x2 << 2), %al
outb %al, %dx
/* clear any lingering errors, so the transaction will run */
movl $(SMBUS_IO_BASE + SMBHSTSTAT), %edx
inb %dx, %al
outb %al, %dx
/* clear the data byte... */
movl $(SMBUS_IO_BASE + SMBHSTDAT0), %edx
xorl %eax, %eax
outb %al, %dx
/* start a byte read, with interrupts disabled */
movl $(SMBUS_IO_BASE + SMBHSTCTL), %edx
inb %dx, %al
orb $0x40, %al
outb %al, %dx
/* poll for transaction completion */
SMBUS_WAIT_UNTIL_DONE()
jc smbus_read_byte_failed
/* read the results and see if we succeded */
movl $(SMBUS_IO_BASE + SMBHSTSTAT), %edx
inb %dx, %al
andb $~(1 << 6), %al /* Ignore the In Use Status... */
cmpb $0x02, %al
jne smbus_read_byte_failed
movl $(SMBUS_IO_BASE + SMBHSTDAT0), %edx
testl %edx, %edx /* clear zf */
inb %dx, %al
smbus_read_byte_done:
RETSP
smbus_read_byte_failed:
SMBUS_KILL_COMMAND()
xorl %eax, %eax /* set zf */
jmp smbus_read_byte_done
.previous

View file

@ -1,7 +1,7 @@
#include <superio/generic.h>
#include <superio/w83627hf.h>
void power_led(int state)
void w83627hf_power_led(int state)
{
unsigned char byte;

View file

@ -1,7 +1,7 @@
#include <superio/generic.h>
#include <superio/w83627hf.h>
void w832627hf_power_after_power_fail(int state)
void w83627hf_power_after_power_fail(int state)
{
unsigned char byte;
w83627hf_enter_pnp(SIO_BASE);

View file

@ -1,6 +1,6 @@
include Makefile.conf
VERSION:=1.15
RELEASE_DATE:=23 August 2002
VERSION:=1.16
RELEASE_DATE:=29 August 2002
PACKAGE:=mkelfImage
# You can specify DESTDIR on the command line to do a add
@ -16,23 +16,24 @@ MANS=mkelfImage.1
SPEC=mkelfImage-$(VERSION).spec
TARBALL=mkelfImage-$(VERSION).tar.gz
SRCS:=$(shell find ./AUTHORS ./COPYING ./Makefile ./Makefile.conf.in ./News \
./mkelfImage.pl ./elf32-i386 ./kunzip_src \
./configure.in ./configure ./config \
./configure.in ./configure \
./mkelfImage.pl ./mkelfImage.spec.in \
./elf32-i386 ./kunzip_src ./config \
! -path '*CVS*' ! -name '*~' ! -name '.*' -type f -print )
SRCS+=$(SPEC)
PSRCS:=$(patsubst ./%,mkelfImage-$(VERSION)/%,$(SRCS))
SBIN_TARGETS=mkelfImage
MAN1_TARGETS=mkelfImage.1
PKGDATADIR_TARGETS=\
elf32-i386/convert_params.c \
elf32-i386/elf_boot.h \
elf32-i386/linuxbios_tables.h \
elf32-i386/elfImage.lds \
elf32-i386/head.S \
elf32-i386/uniform_boot.h
PKGDATADIR_TARGETS_I386=\
elf32-i386/convert_params.c \
elf32-i386/elf_boot.h \
elf32-i386/linuxbios_tables.h \
elf32-i386/elfImage.lds \
elf32-i386/head.S \
elf32-i386/uniform_boot.h
TARGETS:=$(SBIN_TARGETS) $(MAN1_TARGETS) $(PKGDATADIR_TARGETS)
TARGETS:=$(SBIN_TARGETS) $(MAN1_TARGETS) $(PKGDATADIR_TARGETS_I386)
all: $(TARGETS)
@ -51,10 +52,10 @@ maintainer-clean: dist-clean
install: $(TARGETS)
mkdir -p $(DESTDIR)/$(pkgdatadir) $(DESTDIR)/$(sbindir) $(DESTDIR)/$(mandir)/man1
cp -a $(SBIN_TARGETS) $(DESTDIR)/$(sbindir)/
cp -a $(MAN1_TARGETS) $(DESTDIR)/$(mandir)/man1/
cp -a $(PKGDATADIR_TARGETS) $(DESTDIR)/$(pkgdatadir)/
mkdir -p $(DESTDIR)/$(pkgdatadir)/elf32-i386/ $(DESTDIR)/$(sbindir) $(DESTDIR)/$(mandir)/man1
cp -ar $(SBIN_TARGETS) $(DESTDIR)/$(sbindir)/
cp -ar $(MAN1_TARGETS) $(DESTDIR)/$(mandir)/man1/
cp -ar $(PKGDATADIR_TARGETS_I386) $(DESTDIR)/$(pkgdatadir)/elf32-i386/
%.1 : %.pl Makefile
@ -98,3 +99,5 @@ $(SPEC): mkelfImage.spec.in Makefile
.PHONY: echo install realinstall
echo:
echo $(SRCS)

View file

@ -1,3 +1,7 @@
* 1.16 29 August 2002
- Include the source for my spec file in the tarball.
- Fix the make install target
* 1.15 23 August 2002
- Rewrote the perl ip checksum code to be reasonably fast
- Fixes to the initial parameter passing in head.S thanks to Jake Page <jake@CS.Stanford.EDU>

View file

@ -0,0 +1,49 @@
Summary: make an elf network bootable image for linux
Name: mkelfImage
Version:
Release: 0
Copyright: GPL
Group: Development/Tools
Source0:ftp://ftp.lnxi.com/pub/src/mkelfImage/mkelfImage-%{version}.tar.gz
Packager: Andrew Ip <aip@cwlinux.com>
Requires: perl, gcc, binutils
BuildRoot: %{_tmppath}/%{name}
%description
mkelfImage is a program that makes a elf boot image for linux kernel images.
The image should work with any i386 multiboot compliant boot loader, an ELF boot
loader that passes no options, a loader compliant with the linuxBIOS elf booting
spec or with the linux kexec kernel patch. A key feature here is that nothing
relies upon BIOS calls, but they are made when necessary. This is useful for
systems running linuxbios.
%prep
%setup -q -n %{name}-%{version}
%build
%configure
make
%install
make install DESTDIR=${RPM_BUILD_ROOT}
%files
%defattr(-,root,root)
%{_sbindir}/mkelfImage
%doc News
%doc COPYING
%doc AUTHORS
%{_mandir}/man1/mkelfImage.1.gz
%{_datadir}/mkelfImage/
%changelog
* Mon Aug 26 2002 Joshua Aune <luken@linuxnetworx.com> 1.15-1
- New version
- Merge distro and Eric's spec file
* Fri Aug 23 2002 Eric Biederman <ebiederman@lnxi.com>
- Simplified and incorporated into mkelfImage
* Sat Aug 10 2002 Andrew Ip <aip@cwlinux.com>
- Initial release

View file

@ -2,6 +2,8 @@
#include <stdlib.h>
#include <sys/io.h>
#include <string.h>
#include <ctype.h>
#include "../../src/include/pc80/mc146818rtc.h"
#include "../../src/include/boot/linuxbios_tables.h"
#define CMOS_IMAGE_BUFFER_SIZE 128
@ -101,8 +103,32 @@ void display_usage(void)
}
static void skip_spaces(char *line, char **ptr)
{
if (!isspace(**ptr)) {
printf("Error missing whitespace in line\n%s\n", line);
exit(1);
}
while(isspace(**ptr)) {
(*ptr)++;
}
return;
}
static unsigned long get_number(char *line, char **ptr, int base)
{
unsigned long value;
char *ptr2;
value = strtoul(*ptr, &ptr2, base);
if (ptr2 == *ptr) {
printf("Error missing digits at: \n%s\n in line:\n%s\n",
*ptr, line);
exit(1);
}
*ptr = ptr2;
return value;
}
/* This routine builds the cmos definition table from the cmos configuration file
/* This routine builds the cmos definition table from the cmos layout file
input The input comes from the configuration file which contains two parts
entries and enumerations. Each section is started with the key words
entries and enumerations. Records then follow in their respective
@ -123,10 +149,12 @@ int main(int argc, char **argv)
struct cmos_option_table *ct;
struct cmos_entries *ce;
struct cmos_enums *c_enums, *c_enums_start;
struct cmos_checksum *cs;
unsigned char line[INPUT_LINE_MAX];
unsigned char uc;
int entry_mode=0;
int enum_mode=0;
int checksum_mode=0;
int ptr,cnt;
char *cptr;
int offset,entry_start;
@ -176,8 +204,8 @@ int main(int argc, char **argv)
}
}
else { /* no configuration file specified, so try the default */
if((fp=fopen("cmos.conf","r"))==NULL){
printf("Error - Can not open cmos.conf\n");
if((fp=fopen("cmos.layout","r"))==NULL){
printf("Error - Can not open cmos.layout\n");
exit(1); /* end of no configuration file is found */
}
}
@ -187,6 +215,7 @@ int main(int argc, char **argv)
ct->tag = LB_TAG_CMOS_OPTION_TABLE;
/* put in the header length */
ct->header_length=sizeof(*ct);
/* Get the entry records */
ce=(struct cmos_entries*)(cmos_table+(ct->header_length));
cptr = (char*)ce;
@ -194,18 +223,24 @@ int main(int argc, char **argv)
if(fgets(line,INPUT_LINE_MAX,fp)==NULL)
break; /* end if no more input */
if(!entry_mode) { /* skip input until the entries key word */
if((ptr=(int)strstr(line,"entries"))){
if (strstr(line,"entries") != 0) {
entry_mode=1;
continue;
}
}
else{ /* Test if we are done with entries and starting enumerations */
if((ptr=(int)strstr(line,"enumerations"))){
if (strstr(line,"enumerations") != 0){
entry_mode=0;
enum_mode=1;
break;
}
if (strstr(line, "checksums") != 0) {
enum_mode=0;
checksum_mode=1;
break;
}
}
/* skip commented and blank lines */
if(line[0]=='#') continue;
if(line[strspn(line," ")]=='\n') continue;
@ -248,7 +283,15 @@ int main(int argc, char **argv)
test_for_entry_overlaps(entry_start,offset);
for(;enum_mode;){ /* loop to build the enumerations section */
if(fgets(line,INPUT_LINE_MAX,fp)==NULL) break; /* go till end of input */
if(fgets(line,INPUT_LINE_MAX,fp)==NULL)
break; /* go till end of input */
if (strstr(line, "checksums") != 0) {
enum_mode=0;
checksum_mode=1;
break;
}
/* skip commented and blank lines */
if(line[0]=='#') continue;
if(line[strspn(line," ")]=='\n') continue;
@ -279,6 +322,86 @@ int main(int argc, char **argv)
/* save the enumerations length */
enum_length=(int)c_enums-(int)c_enums_start;
ct->size=ct->header_length+enum_length+entries_length;
/* Get the checksum records */
cs=(struct cmos_checksum *)(cmos_table+(ct->size));
cptr = (char*)cs;
for(;checksum_mode;) { /* This section finds the checksums */
char *ptr;
if(fgets(line, INPUT_LINE_MAX,fp)==NULL)
break; /* end if no more input */
printf("line: %s\n", line);
/* skip commented and blank lines */
if (line[0]=='#') continue;
if (line[strspn(line, " ")]=='\n') continue;
if (memcmp(line, "checksum", 8) != 0) continue;
printf("Found checksum record: \n");
/* get the information */
ptr = line + 8;
skip_spaces(line, &ptr);
cs->range_start = get_number(line, &ptr, 10);
skip_spaces(line, &ptr);
cs->range_end = get_number(line, &ptr, 10);
skip_spaces(line, &ptr);
cs->location = get_number(line, &ptr, 10);
/* Make certain there are spaces until the end of the line */
skip_spaces(line, &ptr);
if ((cs->range_start%8) != 0) {
printf("Error - range start is not byte aligned in line\n%s\n", line);
exit(1);
}
if (cs->range_start >= (CMOS_IMAGE_BUFFER_SIZE*8)) {
printf("Error - range start is to big in line\n%s\n", line);
exit(1);
}
if ((cs->range_end%8) != 7) {
printf("Error - range end is not byte aligned in line\n%s\n", line);
exit(1);
}
if ((cs->range_end) >= (CMOS_IMAGE_BUFFER_SIZE*8)) {
printf("Error - range end is to long in line\n%s\n", line);
exit(1);
}
if ((cs->location%8) != 0) {
printf("Error - location is not byte aligned in line\n%s\n", line);
exit(1);
}
if ((cs->location >= (CMOS_IMAGE_BUFFER_SIZE*8)) ||
((cs->location + 16) > (CMOS_IMAGE_BUFFER_SIZE*8)))
{
printf("Error - location is to big in line\n%s\n", line);
exit(1);
}
/* And since we are not ready to be fully general purpose yet.. */
if ((cs->range_start/8) != LB_CKS_RANGE_START) {
printf("Error - Range start(%d) does not match define(%d) in line\n%s\n",
cs->range_start/8, LB_CKS_RANGE_START, line);
exit(1);
}
if ((cs->range_end/8) != LB_CKS_RANGE_END) {
printf("Error - Range end does not match define in line\n%s\n", line);
exit(1);
}
if ((cs->location/8) != LB_CKS_LOC) {
printf("Error - Location does not match define in line\n%s\n", line);
exit(1);
}
cs->tag = LB_TAG_OPTION_CHECKSUM;
cs->size = sizeof(*cs);
cs->type = CHECKSUM_PCBIOS;
cptr = (char *)cs;
cptr += cs->size;
cs = (struct cmos_checksum *)cptr;
}
ct->size += (cptr - (char *)(cmos_table + ct->size));
fclose(fp);
/* test if an alternate file is to be created */