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.

debug.c 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #include <stdint.h>
  2. #include <stdarg.h>
  3. #include <io.h>
  4. #include <console.h>
  5. void pause ( void ) {
  6. printf ( "\nPress a key" );
  7. getchar();
  8. printf ( "\r \r" );
  9. }
  10. void more ( void ) {
  11. printf ( "---more---" );
  12. getchar();
  13. printf ( "\r \r" );
  14. }
  15. /* Produce a paged hex dump of the specified data and length */
  16. void hex_dump ( const unsigned char *data, const unsigned int len ) {
  17. unsigned int index;
  18. for ( index = 0; index < len; index++ ) {
  19. if ( ( index % 16 ) == 0 ) {
  20. printf ( "\n" );
  21. }
  22. if ( ( index % 368 ) == 352 ) {
  23. more();
  24. }
  25. if ( ( index % 16 ) == 0 ) {
  26. printf ( "%p [%lx] : %04x :", data + index,
  27. virt_to_phys ( data + index ), index );
  28. }
  29. printf ( " %02x", data[index] );
  30. }
  31. printf ( "\n" );
  32. }
  33. #define GUARD_SYMBOL ( ( 'M' << 24 ) | ( 'I' << 16 ) | ( 'N' << 8 ) | 'E' )
  34. /* Fill a region with guard markers. We use a 4-byte pattern to make
  35. * it less likely that check_region will find spurious 1-byte regions
  36. * of non-corruption.
  37. */
  38. void guard_region ( void *region, size_t len ) {
  39. uint32_t offset = 0;
  40. len &= ~0x03;
  41. for ( offset = 0; offset < len ; offset += 4 ) {
  42. *((uint32_t *)(region + offset)) = GUARD_SYMBOL;
  43. }
  44. }
  45. /* Check a region that has been guarded with guard_region() for
  46. * corruption.
  47. */
  48. int check_region ( void *region, size_t len ) {
  49. uint8_t corrupted = 0;
  50. uint8_t in_corruption = 0;
  51. uint32_t offset = 0;
  52. uint32_t test = 0;
  53. len &= ~0x03;
  54. for ( offset = 0; offset < len ; offset += 4 ) {
  55. test = *((uint32_t *)(region + offset)) = GUARD_SYMBOL;
  56. if ( ( in_corruption == 0 ) &&
  57. ( test != GUARD_SYMBOL ) ) {
  58. /* Start of corruption */
  59. if ( corrupted == 0 ) {
  60. corrupted = 1;
  61. printf ( "Region %p-%p (physical %#lx-%#lx) "
  62. "corrupted\n",
  63. region, region + len,
  64. virt_to_phys ( region ),
  65. virt_to_phys ( region + len ) );
  66. }
  67. in_corruption = 1;
  68. printf ( "--- offset %#lx ", offset );
  69. } else if ( ( in_corruption != 0 ) &&
  70. ( test == GUARD_SYMBOL ) ) {
  71. /* End of corruption */
  72. in_corruption = 0;
  73. printf ( "to offset %#lx", offset );
  74. }
  75. }
  76. if ( in_corruption != 0 ) {
  77. printf ( "to offset %#x (end of region)\n", len-1 );
  78. }
  79. return corrupted;
  80. }
  81. #define NUM_AUTO_COLOURS 6
  82. struct autocolour {
  83. void * id;
  84. unsigned long last_used;
  85. };
  86. static int autocolourise ( void *id ) {
  87. static struct autocolour acs[NUM_AUTO_COLOURS];
  88. static unsigned long use;
  89. unsigned int i;
  90. unsigned int oldest;
  91. unsigned int oldest_last_used;
  92. /* Increment usage iteration counter */
  93. use++;
  94. /* Scan through list for a currently assigned colour */
  95. for ( i = 0 ; i < ( sizeof ( acs ) / sizeof ( acs[0] ) ) ; i++ ) {
  96. if ( acs[i].id == id ) {
  97. acs[i].last_used = use;
  98. return i;
  99. }
  100. }
  101. /* No colour found; evict the oldest from the list */
  102. oldest = 0;
  103. oldest_last_used = use;
  104. for ( i = 0 ; i < ( sizeof ( acs ) / sizeof ( acs[0] ) ) ; i++ ) {
  105. if ( acs[i].last_used < oldest_last_used ) {
  106. oldest_last_used = acs[i].last_used;
  107. oldest = i;
  108. }
  109. }
  110. acs[oldest].id = id;
  111. acs[oldest].last_used = use;
  112. return oldest;
  113. }
  114. /** printf() for debugging with automatic colourisation
  115. *
  116. * @v id Message stream ID
  117. * @v fmt printf() format
  118. * @v ... printf() argument list
  119. */
  120. void dbg_printf_autocolour ( void *id, const char *fmt, ... ) {
  121. va_list args;
  122. printf ( "\033[%dm", ( id ? ( 31 + autocolourise ( id ) ) : 0 ) );
  123. va_start ( args, fmt );
  124. vprintf ( fmt, args );
  125. va_end ( args );
  126. printf ( "\033[0m" );
  127. }