mirror of
https://github.com/ipxe/ipxe
synced 2025-12-26 01:22:37 +03:00
[timer] Formalise the timer API
We now have two implementations for the timer API: one using the time-of-day counter at 40:70 and one using RDTSC. Both make use of timer2_udelay().
This commit is contained in:
@@ -5,7 +5,6 @@
|
||||
#define BDA_FBMS 0x0013
|
||||
#define BDA_NUM_DRIVES 0x0075
|
||||
|
||||
extern unsigned long currticks ( void );
|
||||
extern void cpu_nap ( void );
|
||||
|
||||
#endif /* BIOS_H */
|
||||
|
||||
13
src/arch/i386/include/bits/timer.h
Normal file
13
src/arch/i386/include/bits/timer.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef _BITS_TIMER_H
|
||||
#define _BITS_TIMER_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* i386-specific timer API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
#include <gpxe/bios_timer.h>
|
||||
#include <gpxe/rdtsc_timer.h>
|
||||
|
||||
#endif /* _BITS_TIMER_H */
|
||||
@@ -1,8 +0,0 @@
|
||||
#ifndef BITS_TIMER2_H
|
||||
#define BITS_TIMER2_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
void i386_timer2_udelay(unsigned int usecs);
|
||||
|
||||
#endif
|
||||
42
src/arch/i386/include/gpxe/bios_timer.h
Normal file
42
src/arch/i386/include/gpxe/bios_timer.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef _GPXE_BIOS_TIMER_H
|
||||
#define _GPXE_BIOS_TIMER_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* BIOS timer
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef TIMER_PCBIOS
|
||||
#define TIMER_PREFIX_pcbios
|
||||
#else
|
||||
#define TIMER_PREFIX_pcbios __pcbios_
|
||||
#endif
|
||||
|
||||
#include <gpxe/timer2.h>
|
||||
|
||||
/**
|
||||
* Delay for a fixed number of microseconds
|
||||
*
|
||||
* @v usecs Number of microseconds for which to delay
|
||||
*/
|
||||
static inline __always_inline void
|
||||
TIMER_INLINE ( pcbios, udelay ) ( unsigned long usecs ) {
|
||||
/* BIOS timer is not high-resolution enough for udelay(), so
|
||||
* we use timer2
|
||||
*/
|
||||
timer2_udelay ( usecs );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of ticks per second
|
||||
*
|
||||
* @ret ticks_per_sec Number of ticks per second
|
||||
*/
|
||||
static inline __always_inline unsigned long
|
||||
TIMER_INLINE ( pcbios, ticks_per_sec ) ( void ) {
|
||||
/* BIOS timer ticks over at 18.2 ticks per second */
|
||||
return 18;
|
||||
}
|
||||
|
||||
#endif /* _GPXE_BIOS_TIMER_H */
|
||||
37
src/arch/i386/include/gpxe/rdtsc_timer.h
Normal file
37
src/arch/i386/include/gpxe/rdtsc_timer.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef _GPXE_RDTSC_TIMER_H
|
||||
#define _GPXE_RDTSC_TIMER_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* RDTSC timer
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef TIMER_RDTSC
|
||||
#define TIMER_PREFIX_rdtsc
|
||||
#else
|
||||
#define TIMER_PREFIX_rdtsc __rdtsc_
|
||||
#endif
|
||||
|
||||
/**
|
||||
* RDTSC values can easily overflow an unsigned long. We discard the
|
||||
* low-order bits in order to obtain sensibly-scaled values.
|
||||
*/
|
||||
#define TSC_SHIFT 8
|
||||
|
||||
/**
|
||||
* Get current system time in ticks
|
||||
*
|
||||
* @ret ticks Current time, in ticks
|
||||
*/
|
||||
static inline __always_inline unsigned long
|
||||
TIMER_INLINE ( rdtsc, currticks ) ( void ) {
|
||||
unsigned long ticks;
|
||||
|
||||
__asm__ __volatile__ ( "rdtsc\n\t"
|
||||
"shrdl %1, %%edx, %%eax\n\t"
|
||||
: "=a" ( ticks ) : "i" ( TSC_SHIFT ) : "edx" );
|
||||
return ticks;
|
||||
}
|
||||
|
||||
#endif /* _GPXE_RDTSC_TIMER_H */
|
||||
12
src/arch/i386/include/gpxe/timer2.h
Normal file
12
src/arch/i386/include/gpxe/timer2.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef _GPXE_TIMER2_H
|
||||
#define _GPXE_TIMER2_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Timer chip control
|
||||
*
|
||||
*/
|
||||
|
||||
extern void timer2_udelay ( unsigned long usecs );
|
||||
|
||||
#endif /* _GPXE_TIMER2_H */
|
||||
Reference in New Issue
Block a user