iPXE
Defines | Functions | Variables
acpi_timer.c File Reference

ACPI power management timer. More...

#include <unistd.h>
#include <errno.h>
#include <assert.h>
#include <byteswap.h>
#include <ipxe/io.h>
#include <ipxe/acpi.h>

Go to the source code of this file.

Defines

#define ACPI_TIMER_HZ   3579545
 ACPI timer frequency (fixed 3.579545MHz)
#define ACPI_TIMER_MASK   0x00ffffffUL
 ACPI timer mask.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
struct timer acpi_timer __timer (TIMER_PREFERRED)
 ACPI timer.
static unsigned long acpi_currticks (void)
 Get current system time in ticks.
static void acpi_udelay (unsigned long usecs)
 Delay for a fixed number of microseconds.
static int acpi_timer_probe (void)
 Probe ACPI power management timer.

Variables

static unsigned int pm_tmr
 Power management timer register address.

Detailed Description

ACPI power management timer.

Definition in file acpi_timer.c.


Define Documentation

#define ACPI_TIMER_HZ   3579545

ACPI timer frequency (fixed 3.579545MHz)

Definition at line 40 of file acpi_timer.c.

Referenced by acpi_currticks(), and acpi_udelay().

#define ACPI_TIMER_MASK   0x00ffffffUL

ACPI timer mask.

Timers may be implemented as either 24-bit or 32-bit counters. We simplify the code by pessimistically assuming that the timer has only 24 bits.

Definition at line 48 of file acpi_timer.c.

Referenced by acpi_currticks(), and acpi_udelay().


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
struct timer acpi_timer __timer ( TIMER_PREFERRED  ) [read]

ACPI timer.

static unsigned long acpi_currticks ( void  ) [static]

Get current system time in ticks.

Return values:
ticksCurrent time, in ticks

Definition at line 60 of file acpi_timer.c.

References ACPI_TIMER_HZ, ACPI_TIMER_MASK, inl(), offset, pm_tmr, and TICKS_PER_SEC.

                                             {
        static unsigned long offset;
        static uint32_t prev;
        uint32_t now;

        /* Read timer and account for wraparound */
        now = ( inl ( pm_tmr ) & ACPI_TIMER_MASK );
        if ( now < prev ) {
                offset += ( ( ACPI_TIMER_MASK + 1 ) /
                            ( ACPI_TIMER_HZ / TICKS_PER_SEC ) );
        }
        prev = now;

        /* Convert to timer ticks */
        return ( offset + ( now / ( ACPI_TIMER_HZ / TICKS_PER_SEC ) ) );
}
static void acpi_udelay ( unsigned long  usecs) [static]

Delay for a fixed number of microseconds.

Parameters:
usecsNumber of microseconds for which to delay

Definition at line 82 of file acpi_timer.c.

References ACPI_TIMER_HZ, ACPI_TIMER_MASK, inl(), pm_tmr, and start.

                                                {
        uint32_t start;
        uint32_t elapsed;
        uint32_t threshold;

        /* Delay until a suitable number of ticks have elapsed.  We do
         * not need to allow for multiple wraparound, since the
         * wraparound period for a 24-bit timer at 3.579545MHz is
         * around 4700000us.
         */
        start = inl ( pm_tmr );
        threshold = ( ( usecs * ACPI_TIMER_HZ ) / 1000000 );
        do {
                elapsed = ( ( inl ( pm_tmr ) - start ) & ACPI_TIMER_MASK );
        } while ( elapsed < threshold );
}
static int acpi_timer_probe ( void  ) [static]

Probe ACPI power management timer.

Return values:
rcReturn status code

Definition at line 104 of file acpi_timer.c.

References acpi_find(), ACPI_PM_TMR, copy_from_user(), DBGC, ENOENT, FADT_SIGNATURE, le32_to_cpu, pm_tmr, and acpi_fadt::pm_tmr_blk.

                                     {
        struct acpi_fadt fadtab;
        userptr_t fadt;
        unsigned int pm_tmr_blk;

        /* Locate FADT */
        fadt = acpi_find ( FADT_SIGNATURE, 0 );
        if ( ! fadt ) {
                DBGC ( &acpi_timer, "ACPI could not find FADT\n" );
                return -ENOENT;
        }

        /* Read FADT */
        copy_from_user ( &fadtab, fadt, 0, sizeof ( fadtab ) );
        pm_tmr_blk = le32_to_cpu ( fadtab.pm_tmr_blk );
        if ( ! pm_tmr_blk ) {
                DBGC ( &acpi_timer, "ACPI has no timer\n" );
                return -ENOENT;
        }

        /* Record power management timer register address */
        pm_tmr = ( pm_tmr_blk + ACPI_PM_TMR );

        return 0;
}

Variable Documentation

unsigned int pm_tmr [static]

Power management timer register address.

Definition at line 51 of file acpi_timer.c.

Referenced by acpi_currticks(), acpi_timer_probe(), and acpi_udelay().