diff options
author | Andy Lutomirski <luto@amacapital.net> | 2014-06-14 09:25:32 -0700 |
---|---|---|
committer | Andy Lutomirski <luto@amacapital.net> | 2014-06-14 09:25:32 -0700 |
commit | 2a3443b531b30cd4aab424d3b2002208ff957474 (patch) | |
tree | aed2fa662567922d6ddd1b088e3ff057f1900ef7 | |
parent | e64b42b0a1d39c154941329284c7ff3f47c32cd7 (diff) | |
download | misc-tests-2a3443b531b30cd4aab424d3b2002208ff957474.tar.gz |
user_visible_state: Add LAR support
-rw-r--r-- | user_visible_state.c | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/user_visible_state.c b/user_visible_state.c index 055de34..bf289e5 100644 --- a/user_visible_state.c +++ b/user_visible_state.c @@ -61,18 +61,43 @@ static void show_rdtscp(void) printf("RDTSCP: cpu %d\n", cpu); } -static void show_seglimit(uint16_t index) +static void show_segment(uint16_t index) { - uint32_t okay = 0, limit; + uint32_t has_limit = 0, has_ar = 0, limit, ar; asm ("lsl %[index], %[limit]\n\t" "jnz 1f\n\t" - "mov $1, %[okay]\n\t" + "mov $1, %[has_limit]\n\t" "1:" - : [limit] "=r" (limit), [okay] "+rm" (okay) + : [limit] "=r" (limit), [has_limit] "+rm" (has_limit) : [index] "r" ((index << 3) + 3)); - if (okay) { - printf("GDT entry %02hu limit: 0x%08X\n", index, limit); + asm ("larl %[index], %[ar]\n\t" + "jnz 1f\n\t" + "mov $1, %[has_ar]\n\t" + "1:" + : [ar] "=r" (ar), [has_ar] "+rm" (has_ar) + : [index] "r" ((index << 3) + 3)); + + if (!has_limit && !has_ar) + return; + + printf("GDT entry %02hu", index); + + if (has_limit) + printf(" limit: 0x%08X", limit); + + if (has_ar) { +#define ARBITS(low, high) ((ar >> low) & ((1 << (high - low + 1)) - 1)) +#define ARSTR(bit, str) (ARBITS(bit,bit) ? " " str : "") + printf(" access rights: 0x%08X (type=%d DPL=%d%s%s%s%s%s%s)", + ar, ARBITS(8,11), ARBITS(13,14), + ARSTR(12, "S"), ARSTR(15, "P"), + ARSTR(20, "software-available"), + ARSTR(21, "L"), ARSTR(22, "D/B"), ARSTR(23, "G")); +#undef ARSTR +#undef ARBITS } + + printf("\n"); } int main() @@ -84,5 +109,5 @@ int main() show_flags(); show_rdtscp(); for (int i = 0; i <= gdtlimit; i++) - show_seglimit(i); + show_segment(i); } |