您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

virtaddr.h 2.4KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #ifndef VIRTADDR_H
  2. #define VIRTADDR_H
  3. /* Segment selectors as used in our protected-mode GDTs.
  4. *
  5. * Don't change these unless you really know what you're doing.
  6. */
  7. #define PHYSICAL_CS 0x08
  8. #define PHYSICAL_DS 0x10
  9. #define VIRTUAL_CS 0x18
  10. #define VIRTUAL_DS 0x20
  11. #define LONG_CS 0x28
  12. #define LONG_DS 0x30
  13. #ifndef ASSEMBLY
  14. #include "stdint.h"
  15. #ifndef KEEP_IT_REAL
  16. /*
  17. * Without -DKEEP_IT_REAL, we are in 32-bit protected mode with a
  18. * fixed link address but an unknown physical start address. Our GDT
  19. * sets up code and data segments with an offset of virt_offset, so
  20. * that link-time addresses can still work.
  21. *
  22. */
  23. /* C-callable function prototypes */
  24. extern void relocate_to ( uint32_t new_phys_addr );
  25. /* Variables in virtaddr.S */
  26. extern unsigned long virt_offset;
  27. /*
  28. * Convert between virtual and physical addresses
  29. *
  30. */
  31. static inline unsigned long virt_to_phys ( volatile const void *virt_addr ) {
  32. return ( ( unsigned long ) virt_addr ) + virt_offset;
  33. }
  34. static inline void * phys_to_virt ( unsigned long phys_addr ) {
  35. return ( void * ) ( phys_addr - virt_offset );
  36. }
  37. #else /* KEEP_IT_REAL */
  38. /*
  39. * With -DKEEP_IT_REAL, we are in 16-bit real mode with fixed link
  40. * addresses and a segmented memory model. We have separate code and
  41. * data segments.
  42. *
  43. * Because we may be called in 16-bit protected mode (damn PXE spec),
  44. * we cannot simply assume that physical = segment * 16 + offset.
  45. * Instead, we have to look up the physical start address of the
  46. * segment in the !PXE structure. We have to assume that
  47. * virt_to_phys() is called only on pointers within the data segment,
  48. * because nothing passes segment information to us.
  49. *
  50. * We don't implement phys_to_virt at all, because there will be many
  51. * addresses that simply cannot be reached via a virtual address when
  52. * the virtual address space is limited to 64kB!
  53. */
  54. static inline unsigned long virt_to_phys ( volatile const void *virt_addr ) {
  55. /* Cheat: just for now, do the segment*16+offset calculation */
  56. uint16_t ds;
  57. __asm__ ( "movw %%ds, %%ax" : "=a" ( ds ) : );
  58. return ( 16 * ds + ( ( unsigned long ) virt_addr ) );
  59. }
  60. /* Define it as a deprecated function so that we get compile-time
  61. * warnings, rather than just the link-time errors.
  62. */
  63. extern void * phys_to_virt ( unsigned long phys_addr )
  64. __attribute__ ((deprecated));
  65. #endif /* KEEP_IT_REAL */
  66. #endif /* ASSEMBLY */
  67. #endif /* VIRTADDR_H */