diff --git a/src/DebugServer/Gdb/CommandPackets/ListRegistersMonitor.cpp b/src/DebugServer/Gdb/CommandPackets/ListRegistersMonitor.cpp index 2c77dd56..de89ab06 100644 --- a/src/DebugServer/Gdb/CommandPackets/ListRegistersMonitor.cpp +++ b/src/DebugServer/Gdb/CommandPackets/ListRegistersMonitor.cpp @@ -73,8 +73,8 @@ namespace DebugServer::Gdb::CommandPackets const auto& registerGroupDescriptor = registerGroupDescriptorOpt->get(); debugSession.connection.writePacket(PartialResponsePacket{StringService::toHex( - peripheralDescriptor.name + " peripheral registers, in " + registerGroupDescriptor.name - + " register group:\n\n" + "\"" + peripheralDescriptor.name + "\" peripheral registers, in \"" + registerGroupDescriptor.name + + "\" register group:\n\n" )}); this->handleRegisterGroupOutput(registerGroupDescriptor, debugSession); debugSession.connection.writePacket(ResponsePacket{StringService::toHex("\n")}); @@ -96,13 +96,13 @@ namespace DebugServer::Gdb::CommandPackets DebugSession& debugSession ) { debugSession.connection.writePacket(PartialResponsePacket{StringService::toHex( - "---------- " + StringService::applyTerminalColor( + "---------- \"" + StringService::applyTerminalColor( peripheralDescriptor.name, StringService::TerminalColor::DARK_GREEN - ) + " (" + StringService::applyTerminalColor( + ) + "\" (`" + StringService::applyTerminalColor( peripheralDescriptor.key, StringService::TerminalColor::DARK_YELLOW - ) + ") peripheral registers ----------\n\n" + ) + "`) peripheral registers ----------\n\n" )}); for (const auto& [groupKey, groupDescriptor] : peripheralDescriptor.registerGroupDescriptorsByKey) { @@ -114,18 +114,18 @@ namespace DebugServer::Gdb::CommandPackets const Targets::TargetRegisterGroupDescriptor& groupDescriptor, DebugSession& debugSession ) { - for (const auto& [registerKey, registerDescriptor] : groupDescriptor.registerDescriptorsByKey) { - auto output = std::string{registerDescriptor.absoluteGroupKey + ", "}; - output += registerDescriptor.key + ", "; - output += registerDescriptor.name + ", "; + for (const auto* registerDescriptor : this->sortRegisterDescriptors(groupDescriptor.registerDescriptorsByKey)) { + auto output = std::string{"`" + registerDescriptor->absoluteGroupKey + "`, "}; + output += "`" + registerDescriptor->key + "`, "; + output += "\"" + registerDescriptor->name + "\", "; output += StringService::applyTerminalColor( - "0x" + StringService::asciiToUpper(StringService::toHex(registerDescriptor.startAddress)), + "0x" + StringService::asciiToUpper(StringService::toHex(registerDescriptor->startAddress)), StringService::TerminalColor::BLUE ) + ", "; - output += std::to_string(registerDescriptor.size * 8) + "-bit"; + output += std::to_string(registerDescriptor->size * 8) + "-bit"; - if (registerDescriptor.description.has_value()) { - output += ", \"" + *(registerDescriptor.description) + "\""; + if (registerDescriptor->description.has_value()) { + output += ", \"" + *(registerDescriptor->description) + "\""; } output += "\n"; @@ -136,4 +136,31 @@ namespace DebugServer::Gdb::CommandPackets this->handleRegisterGroupOutput(subGroupDescriptor, debugSession); } } + + std::vector ListRegistersMonitor::sortRegisterDescriptors( + const std::map>& map + ) { + auto output = std::vector{}; + std::transform( + map.begin(), + map.end(), + std::back_inserter(output), + [] (const auto& pair) { + return &pair.second; + } + ); + + std::sort( + output.begin(), + output.end(), + [] ( + const Targets::TargetRegisterDescriptor* descriptorA, + const Targets::TargetRegisterDescriptor* descriptorB + ) { + return descriptorA->startAddress < descriptorB->startAddress; + } + ); + + return output; + } } diff --git a/src/DebugServer/Gdb/CommandPackets/ListRegistersMonitor.hpp b/src/DebugServer/Gdb/CommandPackets/ListRegistersMonitor.hpp index 8705d3ab..c55b5a18 100644 --- a/src/DebugServer/Gdb/CommandPackets/ListRegistersMonitor.hpp +++ b/src/DebugServer/Gdb/CommandPackets/ListRegistersMonitor.hpp @@ -1,6 +1,9 @@ #pragma once #include +#include +#include +#include #include "Monitor.hpp" @@ -32,5 +35,9 @@ namespace DebugServer::Gdb::CommandPackets const Targets::TargetRegisterGroupDescriptor& groupDescriptor, DebugSession& debugSession ); + + static std::vector sortRegisterDescriptors( + const std::map>& map + ); }; } diff --git a/src/DebugServer/Gdb/CommandPackets/ReadRegistersMonitor.cpp b/src/DebugServer/Gdb/CommandPackets/ReadRegistersMonitor.cpp index ff5ca429..619b09c4 100644 --- a/src/DebugServer/Gdb/CommandPackets/ReadRegistersMonitor.cpp +++ b/src/DebugServer/Gdb/CommandPackets/ReadRegistersMonitor.cpp @@ -1,6 +1,7 @@ #include "ReadRegistersMonitor.hpp" #include +#include #include "src/DebugServer/Gdb/ResponsePackets/ErrorResponsePacket.hpp" #include "src/DebugServer/Gdb/ResponsePackets/PartialResponsePacket.hpp" @@ -77,8 +78,8 @@ namespace DebugServer::Gdb::CommandPackets if (!registerKey.has_value()) { debugSession.connection.writePacket(PartialResponsePacket{StringService::toHex( - "Reading all registers in " + registerGroupDescriptor.name + " register group, from " - + peripheralDescriptor.name + " peripheral...\n\n" + "Reading all registers in \"" + registerGroupDescriptor.name + "\" register group, from \"" + + peripheralDescriptor.name + "\" peripheral...\n\n" )}); this->handleRegisterGroupOutput(registerGroupDescriptor, debugSession, targetControllerService); debugSession.connection.writePacket(ResponsePacket{StringService::toHex("\n")}); @@ -110,7 +111,7 @@ namespace DebugServer::Gdb::CommandPackets DebugSession& debugSession, TargetControllerService& targetControllerService ) { - auto output = std::string{"\nName: " + registerDescriptor.name + "\n"}; + auto output = std::string{"\nName: \"" + registerDescriptor.name + "\"\n"}; output += "Address: " + StringService::applyTerminalColor( "0x" + StringService::asciiToUpper(StringService::toHex(registerDescriptor.startAddress)), StringService::TerminalColor::BLUE @@ -137,9 +138,9 @@ namespace DebugServer::Gdb::CommandPackets StringService::TerminalColor::DARK_YELLOW ) + ")\n"; - for (const auto& [bitFieldKey, bitFieldDescriptor] : registerDescriptor.bitFieldDescriptorsByKey) { - output += bitFieldDescriptor.name + ": " + StringService::applyTerminalColor( - "0b" + StringService::toBinaryStringWithMask(value, bitFieldDescriptor.mask), + for (const auto* bitFieldDescriptor : this->sortBitFieldDescriptors(registerDescriptor.bitFieldDescriptorsByKey)) { + output += bitFieldDescriptor->name + ": " + StringService::applyTerminalColor( + "0b" + StringService::toBinaryStringWithMask(value, bitFieldDescriptor->mask), StringService::TerminalColor::DARK_YELLOW ) + " "; @@ -160,7 +161,7 @@ namespace DebugServer::Gdb::CommandPackets TargetControllerService& targetControllerService ) { debugSession.connection.writePacket(PartialResponsePacket{StringService::toHex( - "Reading " + peripheralDescriptor.name + " peripheral registers...\n\n" + "Reading \"" + peripheralDescriptor.name + "\" peripheral registers...\n\n" )}); for (const auto& [groupKey, groupDescriptor] : peripheralDescriptor.registerGroupDescriptorsByKey) { @@ -175,23 +176,23 @@ namespace DebugServer::Gdb::CommandPackets DebugSession& debugSession, TargetControllerService& targetControllerService ) { - for (const auto& [registerKey, registerDescriptor] : groupDescriptor.registerDescriptorsByKey) { - auto output = std::string{registerDescriptor.absoluteGroupKey + ", "}; - output += registerDescriptor.key + ", "; - output += registerDescriptor.name + ", "; + for (const auto* registerDescriptor : this->sortRegisterDescriptors(groupDescriptor.registerDescriptorsByKey)) { + auto output = std::string{"`" + registerDescriptor->absoluteGroupKey + "`, "}; + output += "`" + registerDescriptor->key + "`, "; + output += "\"" + registerDescriptor->name + "\", "; output += StringService::applyTerminalColor( - "0x" + StringService::asciiToUpper(StringService::toHex(registerDescriptor.startAddress)), + "0x" + StringService::asciiToUpper(StringService::toHex(registerDescriptor->startAddress)), StringService::TerminalColor::BLUE ) + ", "; - output += std::to_string(registerDescriptor.size * 8) + "-bit | "; + output += std::to_string(registerDescriptor->size * 8) + "-bit | "; - if (registerDescriptor.access.readable) { + if (registerDescriptor->access.readable) { const auto value = IntegerService::toUint64( - targetControllerService.readRegister(registerDescriptor) + targetControllerService.readRegister(*registerDescriptor) ); output += StringService::applyTerminalColor( - "0x" + StringService::asciiToUpper(StringService::toHex(value)).substr(16 - (registerDescriptor.size * 2)), + "0x" + StringService::asciiToUpper(StringService::toHex(value)).substr(16 - (registerDescriptor->size * 2)), StringService::TerminalColor::DARK_YELLOW ); output += " (" + StringService::applyTerminalColor( @@ -199,13 +200,13 @@ namespace DebugServer::Gdb::CommandPackets StringService::TerminalColor::DARK_YELLOW ); output += ", " + StringService::applyTerminalColor( - "0b" + std::bitset<64>{value}.to_string().substr(64 - (registerDescriptor.size * 8)), + "0b" + std::bitset<64>{value}.to_string().substr(64 - (registerDescriptor->size * 8)), StringService::TerminalColor::DARK_YELLOW ) + ")"; - for (const auto& [bitFieldKey, bitFieldDescriptor] : registerDescriptor.bitFieldDescriptorsByKey) { - output += ", " + bitFieldDescriptor.name + ": " + StringService::applyTerminalColor( - "0b" + StringService::toBinaryStringWithMask(value, bitFieldDescriptor.mask), + for (const auto* bitFieldDescriptor : this->sortBitFieldDescriptors(registerDescriptor->bitFieldDescriptorsByKey)) { + output += ", " + bitFieldDescriptor->name + ": " + StringService::applyTerminalColor( + "0b" + StringService::toBinaryStringWithMask(value, bitFieldDescriptor->mask), StringService::TerminalColor::DARK_YELLOW ); } @@ -222,4 +223,58 @@ namespace DebugServer::Gdb::CommandPackets this->handleRegisterGroupOutput(subGroupDescriptor, debugSession, targetControllerService); } } + + std::vector ReadRegistersMonitor::sortRegisterDescriptors( + const std::map>& map + ) { + auto output = std::vector{}; + std::transform( + map.begin(), + map.end(), + std::back_inserter(output), + [] (const auto& pair) { + return &pair.second; + } + ); + + std::sort( + output.begin(), + output.end(), + [] ( + const Targets::TargetRegisterDescriptor* descriptorA, + const Targets::TargetRegisterDescriptor* descriptorB + ) { + return descriptorA->startAddress < descriptorB->startAddress; + } + ); + + return output; + } + + std::vector ReadRegistersMonitor::sortBitFieldDescriptors( + const std::map& map + ) { + auto output = std::vector{}; + std::transform( + map.begin(), + map.end(), + std::back_inserter(output), + [] (const auto& pair) { + return &pair.second; + } + ); + + std::sort( + output.begin(), + output.end(), + [] ( + const Targets::TargetBitFieldDescriptor* descriptorA, + const Targets::TargetBitFieldDescriptor* descriptorB + ) { + return descriptorA->mask < descriptorB->mask; + } + ); + + return output; + } } diff --git a/src/DebugServer/Gdb/CommandPackets/ReadRegistersMonitor.hpp b/src/DebugServer/Gdb/CommandPackets/ReadRegistersMonitor.hpp index e179c9b4..fbce62ce 100644 --- a/src/DebugServer/Gdb/CommandPackets/ReadRegistersMonitor.hpp +++ b/src/DebugServer/Gdb/CommandPackets/ReadRegistersMonitor.hpp @@ -1,12 +1,16 @@ #pragma once #include +#include +#include +#include #include "Monitor.hpp" -#include "src/Targets/TargetRegisterDescriptor.hpp" -#include "src/Targets/TargetRegisterGroupDescriptor.hpp" #include "src/Targets/TargetPeripheralDescriptor.hpp" +#include "src/Targets/TargetRegisterGroupDescriptor.hpp" +#include "src/Targets/TargetRegisterDescriptor.hpp" +#include "src/Targets/TargetBitFieldDescriptor.hpp" namespace DebugServer::Gdb::CommandPackets { @@ -40,5 +44,13 @@ namespace DebugServer::Gdb::CommandPackets DebugSession& debugSession, Services::TargetControllerService& targetControllerService ); + + static std::vector sortRegisterDescriptors( + const std::map>& map + ); + + static std::vector sortBitFieldDescriptors( + const std::map& map + ); }; } diff --git a/src/DebugServer/Gdb/CommandPackets/WriteRegisterMonitor.cpp b/src/DebugServer/Gdb/CommandPackets/WriteRegisterMonitor.cpp index ba451cbd..2057a791 100644 --- a/src/DebugServer/Gdb/CommandPackets/WriteRegisterMonitor.cpp +++ b/src/DebugServer/Gdb/CommandPackets/WriteRegisterMonitor.cpp @@ -88,7 +88,7 @@ namespace DebugServer::Gdb::CommandPackets const auto& registerDescriptor = registerDescriptorOpt->get(); if (!registerDescriptor.access.writable) { - throw Exception{registerDescriptor.name + " register is not writeable"}; + throw Exception{"\"" + registerDescriptor.name + "\" register is not writeable"}; } if (registerDescriptor.size > 8) { @@ -120,8 +120,8 @@ namespace DebugServer::Gdb::CommandPackets "Writing value " + StringService::applyTerminalColor( "0x" + StringService::toHex(value).substr(16 - (registerDescriptor.size * 2)), StringService::TerminalColor::DARK_YELLOW - ) + " (" + std::to_string(buffer.size() * 8) + "-bit" + ") to " + registerDescriptor.name - + " register, at address " + StringService::applyTerminalColor( + ) + " (" + std::to_string(buffer.size() * 8) + "-bit" + ") to \"" + registerDescriptor.name + + "\" register, at address " + StringService::applyTerminalColor( "0x" + StringService::toHex(registerDescriptor.startAddress), StringService::TerminalColor::BLUE ) + ", via `" + registerDescriptor.addressSpaceKey + "` address space...\n"