capDL: Remove the old version capDL debugging tool

Remove the old version capDL debugging tool of x86 and arm32

Signed-off-by: Jingyao Zhou <Jingyao.Zhou@data61.csiro.au>
This commit is contained in:
Jingyao Zhou 2020-09-12 01:42:41 +10:00
parent 031b400afc
commit 658e110622
3 changed files with 1 additions and 760 deletions

View file

@ -6,26 +6,3 @@
#pragma once
#define ESCAPE 0xaa
#define START 0xff
#define END 0xbb
#define START_ESCAPE 0xa0
#define ESCAPE_ESCAPE 0xa1
#define END_ESCAPE 0xa2
#define PD_COMMAND 0xf0
#define RQ_COMMAND 0xf1
#define EP_COMMAND 0xf2
#define CN_COMMAND 0xf3
#define TCB_COMMAND 0xfb
#define IRQ_COMMAND 0xf4
#define PT_COMMAND 0xf5
#define ASID_POOL_COMMAND 0xf6
#define IO_PT_COMMAND 0xf7
#define IO_SPACE_COMMAND 0xf8
#define VERSION_COMMAND 0xf9
#define DONE 0xfa
#define CAPDL_VERSION 0

View file

@ -4,355 +4,14 @@
* SPDX-License-Identifier: GPL-2.0-only
*/
#include <config.h>
#include <object/structures.h>
#include <object/tcb.h>
#include <model/statedata.h>
#include <machine/capdl.h>
#include <arch/machine/capdl.h>
#include <machine/io.h>
#include <plat/machine/hardware.h>
#ifdef CONFIG_DEBUG_BUILD
#define ARCH 0xe0
#define PD_READ_SIZE BIT(PD_INDEX_BITS)
#define PT_READ_SIZE BIT(PT_INDEX_BITS)
#define ASID_POOL_READ_SIZE BIT(ASID_POOL_INDEX_BITS)
static int getDecodedChar(unsigned char *result)
{
unsigned char c;
c = getDebugChar();
if (c == START) {
return 1;
}
if (c == ESCAPE) {
c = getDebugChar();
if (c == START) {
return 1;
}
switch (c) {
case ESCAPE_ESCAPE:
*result = ESCAPE;
break;
case START_ESCAPE:
*result = START;
break;
case END_ESCAPE:
*result = END;
break;
default:
if (c >= 20 && c < 40) {
*result = c - 20;
}
}
return 0;
} else {
*result = c;
return 0;
}
}
static void putEncodedChar(unsigned char c)
{
switch (c) {
case ESCAPE:
putDebugChar(ESCAPE);
putDebugChar(ESCAPE_ESCAPE);
break;
case START:
putDebugChar(ESCAPE);
putDebugChar(START_ESCAPE);
break;
case END:
putDebugChar(ESCAPE);
putDebugChar(END_ESCAPE);
break;
default:
if (c < 20) {
putDebugChar(ESCAPE);
putDebugChar(c + 20);
} else {
putDebugChar(c);
}
}
}
static int getArg32(unsigned int *res)
{
unsigned char b1 = 0;
unsigned char b2 = 0;
unsigned char b3 = 0;
unsigned char b4 = 0;
if (getDecodedChar(&b1)) {
return 1;
}
if (getDecodedChar(&b2)) {
return 1;
}
if (getDecodedChar(&b3)) {
return 1;
}
if (getDecodedChar(&b4)) {
return 1;
}
*res = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
return 0;
}
static void sendWord(unsigned int word)
{
putEncodedChar(word & 0xff);
putEncodedChar((word >> 8) & 0xff);
putEncodedChar((word >> 16) & 0xff);
putEncodedChar((word >> 24) & 0xff);
}
static cte_t *getMDBParent(cte_t *slot)
{
cte_t *oldSlot = CTE_PTR(mdb_node_get_mdbPrev(slot->cteMDBNode));
while (oldSlot != 0 && !isMDBParentOf(oldSlot, slot)) {
oldSlot = CTE_PTR(mdb_node_get_mdbPrev(oldSlot->cteMDBNode));
}
return oldSlot;
}
static void sendPD(unsigned int address)
{
word_t i, exists;
pde_t *start = (pde_t *)address;
for (i = 0; i < PD_READ_SIZE; i++) {
pde_t pde = start[i];
exists = 0;
if (pde_get_pdeType(pde) == pde_pde_coarse && pde_pde_coarse_get_address(pde) != 0) {
exists = 1;
} else if (pde_get_pdeType(pde) == pde_pde_section && (pde_pde_section_get_address(pde) != 0 ||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
pde_pde_section_get_HAP(pde))) {
#else
pde_pde_section_get_AP(pde))) {
#endif
exists = 1;
}
if (exists != 0 && i < USER_TOP >> pageBitsForSize(ARMSection)) {
sendWord(i);
sendWord(pde.words[0]);
}
}
}
static void sendPT(unsigned int address)
{
word_t i, exists;
pte_t *start = (pte_t *)address;
for (i = 0; i < PT_READ_SIZE; i++) {
pte_t pte = start[i];
exists = 0;
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
if (pte_get_pteType(pte) == pte_pte_small && (pte_pte_small_get_address(pte) != 0 ||
pte_pte_small_get_HAP(pte))) {
exists = 1;
}
#else
if (pte_get_pteType(pte) == pte_pte_large && (pte_pte_large_get_address(pte) != 0 ||
pte_pte_large_get_AP(pte))) {
exists = 1;
} else if (pte_get_pteType(pte) == pte_pte_small && (pte_pte_small_get_address(pte) != 0 ||
pte_pte_small_get_AP(pte))) {
exists = 1;
}
#endif
if (exists != 0) {
sendWord(i);
sendWord(pte.words[0]);
}
}
}
static void sendASIDPool(unsigned int address)
{
word_t i;
pde_t **start = (pde_t **)address;
for (i = 0; i < ASID_POOL_READ_SIZE; i++) {
pde_t *pde = start[i];
if (pde != 0) {
sendWord(i);
sendWord((unsigned int)pde);
}
}
}
static void sendRunqueues(void)
{
for (uint32_t i = 0; i < CONFIG_MAX_NUM_NODES; i++) {
for (tcb_t *curr = NODE_STATE_ON_CORE(ksDebugTCBs, i); curr != NULL; curr = TCB_PTR_DEBUG_PTR(curr)->tcbDebugNext) {
thread_state_t *state = &curr->tcbState;
if (thread_state_ptr_get_tsType(state) != ThreadState_IdleThreadState &&
thread_state_ptr_get_tsType(state) != ThreadState_Inactive) {
sendWord((unsigned int)curr);
}
}
}
}
static void sendEPQueue(unsigned int epptr)
{
tcb_t *current = (tcb_t *)endpoint_ptr_get_epQueue_head((endpoint_t *)epptr);
for (; current != NULL; current = current->tcbEPNext) {
sendWord((unsigned int)current);
}
}
static void sendCNode(unsigned int address, unsigned int sizebits)
{
word_t i;
cte_t *start = (cte_t *)address;
for (i = 0; i < (1 << sizebits); i++) {
cap_t cap = start[i].cap;
if (cap_get_capType(cap) != cap_null_cap) {
cte_t *parent = getMDBParent(&start[i]);
sendWord(i);
sendWord(cap.words[0]);
sendWord(cap.words[1]);
sendWord((unsigned int)parent);
}
}
}
static void sendIRQNode(void)
{
sendCNode((unsigned int)intStateIRQNode, 8);
}
static void sendVersion(void)
{
sendWord(ARCH);
sendWord(CAPDL_VERSION);
}
void capDL(void)
{
int result;
int done = 0;
while (done == 0) {
unsigned char c;
do {
c = getDebugChar();
} while (c != START);
do {
result = getDecodedChar(&c);
if (result) {
continue;
}
switch (c) {
case PD_COMMAND: {
/*pgdir */
unsigned int arg;
result = getArg32(&arg);
if (result) {
continue;
}
sendPD(arg);
putDebugChar(END);
}
break;
case PT_COMMAND: {
/*pg table */
unsigned int arg;
result = getArg32(&arg);
if (result) {
continue;
}
sendPT(arg);
putDebugChar(END);
}
break;
case ASID_POOL_COMMAND: {
/*asid pool */
unsigned int arg;
result = getArg32(&arg);
if (result) {
continue;
}
sendASIDPool(arg);
putDebugChar(END);
}
break;
case RQ_COMMAND: {
/*runqueues */
sendRunqueues();
putDebugChar(END);
result = 0;
}
break;
case EP_COMMAND: {
/*endpoint waiters */
unsigned int arg;
result = getArg32(&arg);
if (result) {
continue;
}
sendEPQueue(arg);
putDebugChar(END);
}
break;
case CN_COMMAND: {
/*cnode */
unsigned int address, sizebits;
result = getArg32(&address);
if (result) {
continue;
}
result = getArg32(&sizebits);
if (result) {
continue;
}
sendCNode(address, sizebits);
putDebugChar(END);
}
case TCB_COMMAND: {
/*cnode */
unsigned int address, sizebits;
result = getArg32(&address);
if (result) {
continue;
}
result = getArg32(&sizebits);
if (result) {
continue;
}
sendCNode((unsigned int)TCB_PTR_CTE_PTR(address, 0), sizebits);
putDebugChar(END);
}
break;
case IRQ_COMMAND: {
sendIRQNode();
putDebugChar(END);
result = 0;
}
break;
case VERSION_COMMAND: {
sendVersion();
putDebugChar(END);
}
break;
case DONE: {
done = 1;
putDebugChar(END);
}
default:
result = 0;
break;
}
} while (result);
}
}
#endif
#endif

View file

@ -4,398 +4,3 @@
* SPDX-License-Identifier: GPL-2.0-only
*/
#include <config.h>
#include <object/structures.h>
#include <object/tcb.h>
#include <model/statedata.h>
#include <machine/capdl.h>
#include <arch/machine/capdl.h>
#include <machine/io.h>
#ifdef CONFIG_DEBUG_BUILD
#define ARCH 0xe1
#define PD_READ_SIZE BIT(PD_INDEX_BITS)
#define PT_READ_SIZE BIT(PT_INDEX_BITS)
#define ASID_POOL_READ_SIZE BIT(ASID_POOL_INDEX_BITS)
#define IO_PT_READ_SIZE BIT(VTD_PT_INDEX_BITS)
static int getDecodedChar(unsigned char *result)
{
unsigned char c;
c = getDebugChar();
if (c == START) {
return 1;
}
if (c == ESCAPE) {
c = getDebugChar();
if (c == START) {
return 1;
}
switch (c) {
case ESCAPE_ESCAPE:
*result = ESCAPE;
break;
case START_ESCAPE:
*result = START;
break;
case END_ESCAPE:
*result = END;
break;
default:
if (c >= 20 && c < 40) {
*result = c - 20;
} else {
return 1;
}
}
return 0;
} else {
*result = c;
return 0;
}
}
static void putEncodedChar(unsigned char c)
{
switch (c) {
case ESCAPE:
putDebugChar(ESCAPE);
putDebugChar(ESCAPE_ESCAPE);
break;
case START:
putDebugChar(ESCAPE);
putDebugChar(START_ESCAPE);
break;
case END:
putDebugChar(ESCAPE);
putDebugChar(END_ESCAPE);
break;
default:
if (c < 20) {
putDebugChar(ESCAPE);
putDebugChar(c + 20);
} else {
putDebugChar(c);
}
}
}
static int getArg(unsigned long *res)
{
unsigned long i;
unsigned char byte;
*res = 0;
for (i = 0; i < sizeof(unsigned long); i++) {
if (getDecodedChar(&byte)) {
return 1;
}
(*res) = ((*res) << 8) | byte;
}
return 0;
}
static void sendWord(unsigned long word)
{
unsigned long i;
for (i = 0; i < sizeof(unsigned long); i++) {
putEncodedChar((word >> (i * 8)) & 0xff);
}
}
static cte_t *getMDBParent(cte_t *slot)
{
cte_t *oldSlot = CTE_PTR(mdb_node_get_mdbPrev(slot->cteMDBNode));
while (oldSlot != 0 && !isMDBParentOf(oldSlot, slot)) {
oldSlot = CTE_PTR(mdb_node_get_mdbPrev(oldSlot->cteMDBNode));
}
return oldSlot;
}
static void sendPD(unsigned long address)
{
unsigned long i;
unsigned int exists;
pde_t *start = (pde_t *)address;
for (i = 0; i < PD_READ_SIZE; i++) {
pde_t pde = start[i];
exists = 1;
if (pde_get_page_size(pde) == pde_pde_pt && (pde_pde_pt_get_pt_base_address(pde) == 0 ||
!pde_pde_pt_get_present(pde) || !pde_pde_pt_get_super_user(pde))) {
exists = 0;
} else if (pde_get_page_size(pde) == pde_pde_large && (pde_pde_large_get_page_base_address(pde) == 0 ||
!pde_pde_large_get_present(pde) || !pde_pde_large_get_super_user(pde))) {
exists = 0;
}
if (exists != 0 && i < PPTR_BASE >> pageBitsForSize(X86_LargePage)) {
sendWord(i);
sendWord(pde.words[0]);
}
}
}
static void sendPT(unsigned long address)
{
unsigned long i;
pte_t *start = (pte_t *)address;
for (i = 0; i < PT_READ_SIZE; i++) {
pte_t pte = start[i];
if (pte_get_page_base_address(pte) != 0 && pte_get_present(pte) && pte_get_super_user(pte)) {
sendWord(i);
sendWord(pte.words[0]);
}
}
}
static void sendASIDPool(unsigned long address)
{
unsigned long i;
pde_t **start = (pde_t **)address;
for (i = 0; i < ASID_POOL_READ_SIZE; i++) {
pde_t *pde = start[i];
if (pde != 0) {
sendWord(i);
sendWord((unsigned long)pde);
}
}
}
#ifdef CONFIG_IOMMU
static void sendIOPT(unsigned long address, unsigned int level)
{
unsigned long i;
vtd_pte_t *start = (vtd_pte_t *)address;
for (i = 0; i < IO_PT_READ_SIZE; i++) {
vtd_pte_t vtd_pte = start[i];
if (vtd_pte_get_addr(vtd_pte) != 0) {
sendWord(i);
sendWord(vtd_pte.words[0]);
#ifdef CONFIG_ARCH_IA32
sendWord(vtd_pte.words[1]);
#endif
if (level == x86KSnumIOPTLevels) {
sendWord(1);
} else {
sendWord(0);
}
}
}
}
static void sendIOSpace(uint32_t pci_request_id)
{
uint32_t vtd_root_index;
uint32_t vtd_context_index;
vtd_rte_t *vtd_root_slot;
vtd_cte_t *vtd_context;
vtd_cte_t *vtd_context_slot;
vtd_root_index = get_pci_bus(pci_request_id);
vtd_root_slot = x86KSvtdRootTable + vtd_root_index;
vtd_context = (vtd_cte_t *)paddr_to_pptr(vtd_rte_ptr_get_ctp(vtd_root_slot));
vtd_context_index = (get_pci_dev(pci_request_id) << 3) | get_pci_fun(pci_request_id);
vtd_context_slot = &vtd_context[vtd_context_index];
if (vtd_cte_ptr_get_present(vtd_context_slot)) {
sendWord(vtd_cte_ptr_get_asr(vtd_context_slot));
} else {
sendWord(0);
}
}
#endif
static void sendRunqueues(void)
{
word_t i;
sendWord((unsigned long)NODE_STATE(ksCurThread));
for (i = 0; i < NUM_READY_QUEUES; i++) {
tcb_t *current = NODE_STATE(ksReadyQueues[i]).head;
if (current != 0) {
while (current != NODE_STATE(ksReadyQueues[i]).end) {
sendWord((unsigned long)current);
current = current -> tcbSchedNext;
}
sendWord((unsigned long)current);
}
}
}
static void sendEPQueue(unsigned long epptr)
{
tcb_t *current = (tcb_t *)endpoint_ptr_get_epQueue_head((endpoint_t *)epptr);
tcb_t *tail = (tcb_t *)endpoint_ptr_get_epQueue_tail((endpoint_t *)epptr);
if (current == 0) {
return;
}
while (current != tail) {
sendWord((unsigned long)current);
current = current->tcbEPNext;
}
sendWord((unsigned long)current);
}
static void sendCNode(unsigned long address, unsigned int sizebits)
{
unsigned long i;
cte_t *start = (cte_t *)address;
for (i = 0; i < (1 << sizebits); i++) {
cap_t cap = start[i].cap;
if (cap_get_capType(cap) != cap_null_cap) {
cte_t *parent = getMDBParent(&start[i]);
sendWord(i);
sendWord(cap.words[0]);
sendWord(cap.words[1]);
sendWord((unsigned long)parent);
}
}
}
static void sendIRQNode(void)
{
sendCNode((unsigned long)intStateIRQNode, 8);
}
static void sendVersion(void)
{
sendWord(ARCH);
sendWord(CAPDL_VERSION);
}
void capDL(void)
{
int result;
int done = 0;
while (done == 0) {
unsigned char c;
do {
c = getDebugChar();
} while (c != START);
do {
result = getDecodedChar(&c);
if (result) {
continue;
}
switch (c) {
case PD_COMMAND: {
/*pgdir */
unsigned long arg;
result = getArg(&arg);
if (result) {
continue;
}
sendPD(arg);
putDebugChar(END);
}
break;
case PT_COMMAND: {
/*pg table */
unsigned long arg;
result = getArg(&arg);
if (result) {
continue;
}
sendPT(arg);
putDebugChar(END);
}
break;
case ASID_POOL_COMMAND: {
/*asid pool */
unsigned long arg;
result = getArg(&arg);
if (result) {
continue;
}
sendASIDPool(arg);
putDebugChar(END);
}
break;
#ifdef CONFIG_IOMMU
case IO_PT_COMMAND: {
/*io pt table */
unsigned long address, level;
result = getArg(&address);
if (result) {
continue;
}
result = getArg(&level);
if (result) {
continue;
}
sendIOPT(address, level);
putDebugChar(END);
}
break;
case IO_SPACE_COMMAND: {
/*io space */
unsigned long arg;
result = getArg(&arg);
if (result) {
continue;
}
sendIOSpace(arg);
putDebugChar(END);
}
#endif
break;
case RQ_COMMAND: {
/*runqueues */
sendRunqueues();
putDebugChar(END);
result = 0;
}
break;
case EP_COMMAND: {
/*endpoint waiters */
unsigned long arg;
result = getArg(&arg);
if (result) {
continue;
}
sendEPQueue(arg);
putDebugChar(END);
}
break;
case CN_COMMAND: {
/*cnode */
unsigned long address, sizebits;
result = getArg(&address);
if (result) {
continue;
}
result = getArg(&sizebits);
if (result) {
continue;
}
sendCNode(address, sizebits);
putDebugChar(END);
}
break;
case IRQ_COMMAND: {
sendIRQNode();
putDebugChar(END);
result = 0;
}
break;
case VERSION_COMMAND: {
sendVersion();
putDebugChar(END);
}
break;
case DONE: {
done = 1;
putDebugChar(END);
}
default:
result = 0;
break;
}
} while (result);
}
}
#endif