Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

virtaddr.h 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  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 VIRTUAL_CS 0x08
  8. #define VIRTUAL_DS 0x10
  9. #define PHYSICAL_CS 0x18
  10. #define PHYSICAL_DS 0x20
  11. #define REAL_CS 0x28
  12. #define REAL_DS 0x30
  13. #if 0
  14. #define LONG_CS 0x38
  15. #define LONG_DS 0x40
  16. #endif
  17. #ifndef ASSEMBLY
  18. #include "stdint.h"
  19. #include "string.h"
  20. #ifndef KEEP_IT_REAL
  21. /*
  22. * Without -DKEEP_IT_REAL, we are in 32-bit protected mode with a
  23. * fixed link address but an unknown physical start address. Our GDT
  24. * sets up code and data segments with an offset of virt_offset, so
  25. * that link-time addresses can still work.
  26. *
  27. */
  28. /* C-callable function prototypes */
  29. extern void relocate_to ( uint32_t new_phys_addr );
  30. /* Variables in virtaddr.S */
  31. extern unsigned long virt_offset;
  32. /*
  33. * Convert between virtual and physical addresses
  34. *
  35. */
  36. static inline unsigned long virt_to_phys ( volatile const void *virt_addr ) {
  37. return ( ( unsigned long ) virt_addr ) + virt_offset;
  38. }
  39. static inline void * phys_to_virt ( unsigned long phys_addr ) {
  40. return ( void * ) ( phys_addr - virt_offset );
  41. }
  42. static inline void copy_to_phys ( physaddr_t dest, const void *src,
  43. size_t len ) {
  44. memcpy ( phys_to_virt ( dest ), src, len );
  45. }
  46. static inline void copy_from_phys ( void *dest, physaddr_t src, size_t len ) {
  47. memcpy ( dest, phys_to_virt ( src ), len );
  48. }
  49. static inline void copy_phys_to_phys ( physaddr_t dest, physaddr_t src,
  50. size_t len ) {
  51. memcpy ( phys_to_virt ( dest ), phys_to_virt ( src ), len );
  52. }
  53. #else /* KEEP_IT_REAL */
  54. /*
  55. * With -DKEEP_IT_REAL, we are in 16-bit real mode with fixed link
  56. * addresses and a segmented memory model. We have separate code and
  57. * data segments.
  58. *
  59. * Because we may be called in 16-bit protected mode (damn PXE spec),
  60. * we cannot simply assume that physical = segment * 16 + offset.
  61. * Instead, we have to look up the physical start address of the
  62. * segment in the !PXE structure. We have to assume that
  63. * virt_to_phys() is called only on pointers within the data segment,
  64. * because nothing passes segment information to us.
  65. *
  66. * We don't implement phys_to_virt at all, because there will be many
  67. * addresses that simply cannot be reached via a virtual address when
  68. * the virtual address space is limited to 64kB!
  69. */
  70. static inline unsigned long virt_to_phys ( volatile const void *virt_addr ) {
  71. /* Cheat: just for now, do the segment*16+offset calculation */
  72. uint16_t ds;
  73. __asm__ ( "movw %%ds, %%ax" : "=a" ( ds ) : );
  74. return ( 16 * ds + ( ( unsigned long ) virt_addr ) );
  75. }
  76. /* Define it as a deprecated function so that we get compile-time
  77. * warnings, rather than just the link-time errors.
  78. */
  79. extern void * phys_to_virt ( unsigned long phys_addr )
  80. __attribute__ ((deprecated));
  81. #endif /* KEEP_IT_REAL */
  82. #endif /* ASSEMBLY */
  83. #endif /* VIRTADDR_H */