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.
70 lines
1.4 KiB
C
70 lines
1.4 KiB
C
#include <delay.h>
|
|
#include <arch/io.h>
|
|
|
|
/* Ports for the 8254 timer chip */
|
|
#define TIMER2_PORT 0x42
|
|
#define TIMER_MODE_PORT 0x43
|
|
|
|
/* Meaning of the mode bits */
|
|
#define TIMER0_SEL 0x00
|
|
#define TIMER1_SEL 0x40
|
|
#define TIMER2_SEL 0x80
|
|
#define READBACK_SEL 0xC0
|
|
|
|
#define LATCH_COUNT 0x00
|
|
#define LOBYTE_ACCESS 0x10
|
|
#define HIBYTE_ACCESS 0x20
|
|
#define WORD_ACCESS 0x30
|
|
|
|
#define MODE0 0x00
|
|
#define MODE1 0x02
|
|
#define MODE2 0x04
|
|
#define MODE3 0x06
|
|
#define MODE4 0x08
|
|
#define MODE5 0x0A
|
|
|
|
#define BINARY_COUNT 0x00
|
|
#define BCD_COUNT 0x01
|
|
|
|
/* Timers tick over at this rate */
|
|
#define TICKS_PER_MS 1193
|
|
|
|
/* Parallel Peripheral Controller Port B */
|
|
#define PPC_PORTB 0x61
|
|
|
|
/* Meaning of the port bits */
|
|
#define PPCB_T2OUT 0x20 /* Bit 5 */
|
|
#define PPCB_SPKR 0x02 /* Bit 1 */
|
|
#define PPCB_T2GATE 0x01 /* Bit 0 */
|
|
|
|
|
|
static void load_timer2(unsigned int ticks)
|
|
{
|
|
/* Set up the timer gate, turn off the speaker */
|
|
outb((inb(PPC_PORTB) & ~PPCB_SPKR) | PPCB_T2GATE, PPC_PORTB);
|
|
outb(TIMER2_SEL|WORD_ACCESS|MODE0|BINARY_COUNT, TIMER_MODE_PORT);
|
|
outb(ticks & 0xFF, TIMER2_PORT);
|
|
outb(ticks >> 8, TIMER2_PORT);
|
|
}
|
|
|
|
|
|
void udelay(int usecs)
|
|
{
|
|
load_timer2((usecs*TICKS_PER_MS)/1000);
|
|
while ((inb(PPC_PORTB) & PPCB_T2OUT) == 0)
|
|
;
|
|
}
|
|
void mdelay(int msecs)
|
|
{
|
|
int i;
|
|
for(i = 0; i < msecs; i++) {
|
|
udelay(1000);
|
|
}
|
|
}
|
|
void delay(int secs)
|
|
{
|
|
int i;
|
|
for(i = 0; i < secs; i++) {
|
|
mdelay(1000);
|
|
}
|
|
}
|