You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

timer_bios.c 1.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. /*
  2. * Etherboot routines for PCBIOS firmware.
  3. *
  4. * Body of routines taken from old pcbios.S
  5. */
  6. #include <gpxe/init.h>
  7. #include <gpxe/timer.h>
  8. #include <stdio.h>
  9. #include <realmode.h>
  10. #include <bios.h>
  11. #include <bits/timer2.h>
  12. /* A bit faster actually, but we don't care. */
  13. #define TIMER2_TICKS_PER_SEC 18
  14. /*
  15. * Use direct memory access to BIOS variables, longword 0040:006C (ticks
  16. * today) and byte 0040:0070 (midnight crossover flag) instead of calling
  17. * timeofday BIOS interrupt.
  18. */
  19. static tick_t bios_currticks ( void ) {
  20. static int days = 0;
  21. uint32_t ticks;
  22. uint8_t midnight;
  23. /* Re-enable interrupts so that the timer interrupt can occur */
  24. __asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
  25. "nop\n\t"
  26. "nop\n\t"
  27. "cli\n\t" ) : : );
  28. get_real ( ticks, BDA_SEG, 0x006c );
  29. get_real ( midnight, BDA_SEG, 0x0070 );
  30. if ( midnight ) {
  31. midnight = 0;
  32. put_real ( midnight, BDA_SEG, 0x0070 );
  33. days += 0x1800b0;
  34. }
  35. return ( (days + ticks) * (USECS_IN_SEC / TIMER2_TICKS_PER_SEC) );
  36. }
  37. static int bios_ts_init(void)
  38. {
  39. DBG("BIOS timer installed\n");
  40. return 0;
  41. }
  42. struct timer bios_ts __timer ( 02 ) = {
  43. .init = bios_ts_init,
  44. .udelay = i386_timer2_udelay,
  45. .currticks = bios_currticks,
  46. };