portio.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. * (C) Copyright 2003
  3. * Marc Singer, elf@buici.com
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. /*
  8. * Port I/O Functions
  9. *
  10. * Copied from FADS ROM, Dan Malek (dmalek@jlc.net)
  11. */
  12. #include <common.h>
  13. #include <command.h>
  14. /* Display values from last command.
  15. * Memory modify remembered values are different from display memory.
  16. */
  17. static uint in_last_addr, in_last_size;
  18. static uint out_last_addr, out_last_size, out_last_value;
  19. int do_portio_out (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
  20. {
  21. uint addr = out_last_addr;
  22. uint size = out_last_size;
  23. uint value = out_last_value;
  24. if (argc != 3)
  25. return CMD_RET_USAGE;
  26. if ((flag & CMD_FLAG_REPEAT) == 0) {
  27. /*
  28. * New command specified. Check for a size specification.
  29. * Defaults to long if no or incorrect specification.
  30. */
  31. size = cmd_get_data_size (argv[0], 1);
  32. addr = simple_strtoul (argv[1], NULL, 16);
  33. value = simple_strtoul (argv[2], NULL, 16);
  34. }
  35. #if defined (CONFIG_X86)
  36. {
  37. unsigned short port = addr;
  38. switch (size) {
  39. default:
  40. case 1:
  41. {
  42. unsigned char ch = value;
  43. __asm__ volatile ("out %0, %%dx"::"a" (ch), "d" (port));
  44. }
  45. break;
  46. case 2:
  47. {
  48. unsigned short w = value;
  49. __asm__ volatile ("out %0, %%dx"::"a" (w), "d" (port));
  50. }
  51. break;
  52. case 4:
  53. __asm__ volatile ("out %0, %%dx"::"a" (value), "d" (port));
  54. break;
  55. }
  56. }
  57. #endif /* CONFIG_X86 */
  58. out_last_addr = addr;
  59. out_last_size = size;
  60. out_last_value = value;
  61. return 0;
  62. }
  63. U_BOOT_CMD(
  64. out, 3, 1, do_portio_out,
  65. "write datum to IO port",
  66. "[.b, .w, .l] port value\n - output to IO port"
  67. );
  68. int do_portio_in (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
  69. {
  70. uint addr = in_last_addr;
  71. uint size = in_last_size;
  72. if (argc != 2)
  73. return CMD_RET_USAGE;
  74. if ((flag & CMD_FLAG_REPEAT) == 0) {
  75. /*
  76. * New command specified. Check for a size specification.
  77. * Defaults to long if no or incorrect specification.
  78. */
  79. size = cmd_get_data_size (argv[0], 1);
  80. addr = simple_strtoul (argv[1], NULL, 16);
  81. }
  82. #if defined (CONFIG_X86)
  83. {
  84. unsigned short port = addr;
  85. switch (size) {
  86. default:
  87. case 1:
  88. {
  89. unsigned char ch;
  90. __asm__ volatile ("in %%dx, %0":"=a" (ch):"d" (port));
  91. printf (" %02x\n", ch);
  92. }
  93. break;
  94. case 2:
  95. {
  96. unsigned short w;
  97. __asm__ volatile ("in %%dx, %0":"=a" (w):"d" (port));
  98. printf (" %04x\n", w);
  99. }
  100. break;
  101. case 4:
  102. {
  103. unsigned long l;
  104. __asm__ volatile ("in %%dx, %0":"=a" (l):"d" (port));
  105. printf (" %08lx\n", l);
  106. }
  107. break;
  108. }
  109. }
  110. #endif /* CONFIG_X86 */
  111. in_last_addr = addr;
  112. in_last_size = size;
  113. return 0;
  114. }
  115. U_BOOT_CMD(
  116. in, 2, 1, do_portio_in,
  117. "read data from an IO port",
  118. "[.b, .w, .l] port\n"
  119. " - read datum from IO port"
  120. );