io.h 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. #ifndef __LIB_KERNEL_IO_H
  2. #define __LIB_KERNEL_IO_H
  3. #include "stdint.h"
  4. /// @brief 向端口写入一个字节
  5. /// @param port 0~255
  6. /// @param data
  7. static inline void outb(uint16_t port, uint8_t data)
  8. {
  9. // 对端口指定 N 表示 0~255,d 表示用 dx 存储端口号, %b0 表示对应 al,%w1 表示对应 dx
  10. asm volatile("outb %b0, %w1" : : "a"(data), "Nd"(port));
  11. }
  12. /// @brief 将 addr 处起始的 word_cnt 个字写入端口 port
  13. /// @param port 端口号
  14. /// @param addr 地址
  15. /// @param word_cnt 个数
  16. static inline void outsw(uint16_t port, const void *addr, uint32_t word_cnt)
  17. {
  18. // + 表示此限制即做输入又做输出 outsw 是把 ds:esi 处的 16 位的内容写入 port 端口,共写入 word_cnt 个
  19. asm volatile("cld; rep outsw" : "+S"(addr), "+c"(word_cnt) : "d"(port));
  20. }
  21. /// @brief 读取端口 port 的一个字节
  22. /// @param port 端口号
  23. static inline uint8_t inb(uint16_t port)
  24. {
  25. uint8_t data;
  26. asm volatile("inb %w1, %b0" : "=a"(data) : "Nd"(port));
  27. return data;
  28. }
  29. static inline void insw(uint16_t port, void *addr, uint32_t word_cnt)
  30. {
  31. // insw 是把从端口 port 处读入的 16 位内容写入 es:edi 指向的内存,共 word_cnt 个
  32. asm volatile("cld; rep insw" : "+D"(addr), "+c"(word_cnt) : "d"(port) : "memory");
  33. }
  34. #endif // __LIB_KERNEL_IO_H