123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- /* Etherboot routines for PCBIOS firmware.
- *
- * Body of routines taken from old pcbios.S
- */
-
- #ifdef PCBIOS
-
- #include "etherboot.h"
- #include "realmode.h"
- #include "segoff.h"
-
- #define CF ( 1 << 0 )
-
- /**************************************************************************
- CURRTICKS - Get Time
- Use direct memory access to BIOS variables, longword 0040:006C (ticks
- today) and byte 0040:0070 (midnight crossover flag) instead of calling
- timeofday BIOS interrupt.
- **************************************************************************/
- #if defined(CONFIG_TSC_CURRTICKS)
- #undef CONFIG_BIOS_CURRTICKS
- #else
- #define CONFIG_BIOS_CURRTICKS 1
- #endif
- #if defined(CONFIG_BIOS_CURRTICKS)
- unsigned long currticks (void)
- {
- static uint32_t days = 0;
- uint32_t *ticks = VIRTUAL(0x0040,0x006c);
- uint8_t *midnight = VIRTUAL(0x0040,0x0070);
-
- /* Re-enable interrupts so that the timer interrupt can occur
- */
- RM_FRAGMENT(rm_currticks,
- "sti\n\t"
- "nop\n\t"
- "nop\n\t"
- "cli\n\t"
- );
-
- real_call ( rm_currticks, NULL, NULL );
-
- if ( *midnight ) {
- *midnight = 0;
- days += 0x1800b0;
- }
- return ( days + *ticks );
- }
- #endif /* CONFIG_BIOS_CURRTICKS */
-
- /**************************************************************************
- INT15 - Call Interrupt 0x15
- **************************************************************************/
- int int15 ( int ax )
- {
- struct {
- reg16_t ax;
- } PACKED in_stack;
- struct {
- reg16_t flags;
- } PACKED out_stack;
- reg16_t ret_ax;
-
- RM_FRAGMENT(rm_int15,
- "sti\n\t"
- "popw %ax\n\t"
- "stc\n\t"
- "int $0x15\n\t"
- "pushf\n\t"
- "cli\n\t"
- );
-
- in_stack.ax.word = ax;
- ret_ax.word = real_call ( rm_int15, &in_stack, &out_stack );
-
- /* Carry flag clear indicates function not supported */
- if ( ! ( out_stack.flags.word & CF ) ) return 0;
- return ret_ax.h;
- }
-
- #ifdef POWERSAVE
- /**************************************************************************
- CPU_NAP - Save power by halting the CPU until the next interrupt
- **************************************************************************/
- void cpu_nap ( void )
- {
- RM_FRAGMENT(rm_cpu_nap,
- "sti\n\t"
- "hlt\n\t"
- "cli\n\t"
- );
-
- real_call ( rm_cpu_nap, NULL, NULL );
- }
- #endif /* POWERSAVE */
-
- #if (TRY_FLOPPY_FIRST > 0)
- /**************************************************************************
- DISK_INIT - Initialize the disk system
- **************************************************************************/
- void disk_init ( void )
- {
- RM_FRAGMENT(rm_disk_init,
- "sti\n\t"
- "xorw %ax,%ax\n\t"
- "movb $0x80,%dl\n\t"
- "int $0x13\n\t"
- "cli\n\t"
- );
-
- real_call ( rm_disk_init, NULL, NULL );
- }
-
- /**************************************************************************
- DISK_READ - Read a sector from disk
- **************************************************************************/
- unsigned int pcbios_disk_read ( int drive, int cylinder, int head, int sector,
- char *buf ) {
- struct {
- reg16_t ax;
- reg16_t cx;
- reg16_t dx;
- segoff_t buffer;
- } PACKED in_stack;
- struct {
- reg16_t flags;
- } PACKED out_stack;
- reg16_t ret_ax;
-
- RM_FRAGMENT(rm_pcbios_disk_read,
- "sti\n\t"
- "popw %ax\n\t"
- "popw %cx\n\t"
- "popw %dx\n\t"
- "popw %bx\n\t"
- "popw %es\n\t"
- "int $0x13\n\t"
- "pushfw\n\t"
- "cli\n\t"
- );
-
- in_stack.ax.h = 2; /* INT 13,2 - Read disk sector */
- in_stack.ax.l = 1; /* Read one sector */
- in_stack.cx.h = cylinder & 0xff;
- in_stack.cx.l = ( ( cylinder >> 8 ) & 0x3 ) | sector;
- in_stack.dx.h = head;
- in_stack.dx.l = drive;
- in_stack.buffer.segment = SEGMENT ( buf );
- in_stack.buffer.offset = OFFSET ( buf );
- ret_ax.word = real_call ( rm_pcbios_disk_read, &in_stack, &out_stack );
- return ( out_stack.flags.word & CF ) ? ret_ax.word : 0;
- }
- #endif /* TRY_FLOPPY_FIRST */
-
- #endif /* PCBIOS */
|