📄 i386_stub.c
字号:
_msrval[0] = msrval[0];
_msrval[1] = msrval[1];
__set_mem_fault_trap (__do_write_msr);
if (__mem_fault)
return 0;
return 1;
}
int
cyg_hal_stub_process_query (char *pkt, char *buf, int bufsize)
{
unsigned long val1, val2, val3, val4;
int i = 0, max_input = 0;
if ('C' == pkt[0] &&
'P' == pkt[1] &&
'U' == pkt[2] &&
'I' == pkt[3] &&
'D' == pkt[4]) {
for (i = 0; i <= max_input; i++) {
asm volatile ("movl %4,%%eax\n"
"cpuid\n"
"movl %%eax,%0\n"
"movl %%ebx,%1\n"
"movl %%ecx,%2\n"
"movl %%edx,%3\n"
: "=m" (val1), "=m" (val2), "=m" (val3), "=m" (val4)
: "m" (i)
: "eax", "ebx", "ecx", "edx", "memory");
/*
* get the max value to use to get all the CPUID info.
*/
if (i == 0)
max_input = val1;
/*
* Swap the bytes around to handle endianness conversion:
* ie 12345678 --> 78563412
*/
val1 = (((val1 & 0x000000ff) << 24) | ((val1 & 0x0000ff00) << 8) |
((val1 & 0x00ff0000) >> 8) | ((val1 & 0xff000000) >> 24));
val2 = (((val2 & 0x000000ff) << 24) | ((val2 & 0x0000ff00) << 8) |
((val2 & 0x00ff0000) >> 8) | ((val2 & 0xff000000) >> 24));
val3 = (((val3 & 0x000000ff) << 24) | ((val3 & 0x0000ff00) << 8) |
((val3 & 0x00ff0000) >> 8) | ((val3 & 0xff000000) >> 24));
val4 = (((val4 & 0x000000ff) << 24) | ((val4 & 0x0000ff00) << 8) |
((val4 & 0x00ff0000) >> 8) | ((val4 & 0xff000000) >> 24));
/*
* Generate the packet
*/
__mem2hex ((char *)&val1, buf, 8, 0); buf[8] = ','; buf += 9;
__mem2hex ((char *)&val2, buf, 8, 0); buf[8] = ','; buf += 9;
__mem2hex ((char *)&val3, buf, 8, 0); buf[8] = ','; buf += 9;
__mem2hex ((char *)&val4, buf, 8, 0); buf[8] = ';'; buf += 9;
}
/*
* The packet is complete. buf points just past the final semicolon.
* Remove that semicolon and properly terminate the packet.
*/
*(buf - 1) = '\0';
return 1;
}
if ('M' == pkt[0] &&
'S' == pkt[1] &&
'R' == pkt[2]) {
pkt += 4;
if (__hexToInt (&pkt, &val1)) {
target_register_t msrval[2];
// rdmsr implicitly sets _which_msr for subsequent REG_MSR read/write.
if (rdmsr(val1, msrval))
__mem2hex ((char*)msrval, buf, 8, 0);
else
local_memcpy (buf, "INVALID", 8);
}
return 1;
}
return 0;
}
#endif // CYGHWR_HAL_I386_PENTIUM_GDB_REGS
// Write the contents of register WHICH into VALUE as raw bytes. We
// only support this for the MMX, FPU, and SSE registers.
// Return true if it is a valid register.
int
get_register_as_bytes (regnames_t which, char *value)
{
target_register_t offset;
#ifdef CYGHWR_HAL_I386_PENTIUM_GDB_REGS
// Read the currently selected MSR
if (which == REG_MSR) {
if (rdmsr(_which_msr, _msrval)) {
local_memcpy (value, _msrval, REGSIZE(which));
return 1;
}
return 0;
}
// We can't actually read the LDT or TR in software, so just return invalid.
if (which == REG_LDT || which == REG_TR)
return 0;
if (which == REG_GDT || which == REG_IDT) {
// GDB requires these to be sent base first though the CPU stores them
// limit first in 6 bytes. Weird.
offset = reg_offset(which);
local_memcpy (value, (char *)_registers + offset + 2, 4);
local_memcpy (value + 4, (char *)_registers + offset, 2);
return 1;
}
#endif
offset = reg_offset(which);
if (offset != -1) {
local_memcpy (value, (char *)_registers + offset, REGSIZE(which));
return 1;
}
return 0;
}
// Alter the contents of saved register WHICH to contain VALUE. We only
// support this for the MMX, FPU, and SSE registers.
int
put_register_as_bytes (regnames_t which, char *value)
{
target_register_t offset;
#ifdef CYGHWR_HAL_I386_PENTIUM_GDB_REGS
// Write the currently selected MSR
if (which == REG_MSR)
return wrmsr(_which_msr, (target_register_t*)value);
// We can't actually write the LDT OR TR in software, so just return invalid.
if (which == REG_LDT || which == REG_TR)
return 0;
if (which == REG_GDT || which == REG_IDT) {
// GDB sends these base first, though the CPU stores them
// limit first. Weird.
offset = reg_offset(which);
local_memcpy ((char *)_registers + offset + 2, value, 4);
local_memcpy ((char *)_registers + offset, value + 4, 2);
return 1;
}
#endif
offset = reg_offset(which);
if (offset != -1) {
local_memcpy ((char *)_registers + offset, value, REGSIZE(which));
return 1;
}
return 0;
}
/*----------------------------------------------------------------------
* Single-step support
*/
/* Set things up so that the next user resume will execute one instruction.
This may be done by setting breakpoints or setting a single step flag
in the saved user registers, for example. */
/* We just turn on the trap bit in the flags register for the particular
thread. When it resumes, we'll get another debugger trap.
*/
void __single_step (void)
{ put_register(PS, get_register(PS) | PS_T) ;
}
/* Clear the single-step state. */
void __clear_single_step (void)
{ put_register(PS, get_register(PS) & ~PS_T) ;
}
void __install_breakpoints (void)
{
// FIXME();
}
void __clear_breakpoints (void)
{
__clear_breakpoint_list();
}
/* If the breakpoint we hit is in the breakpoint() instruction, return a
non-zero value. */
int isBreakpointFunction ;
int
__is_breakpoint_function ()
{
isBreakpointFunction = (get_register (PC) == (target_register_t)&_breakinst);
return isBreakpointFunction ;
}
/* Skip the current instruction. Since this is only called by the
stub when the PC points to a breakpoint or trap instruction,
we can safely just skip 4. */
void __skipinst (void)
{
// FIXME() ;
}
#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
//----------------------------------------------------------------------
// We apparently need these function even when no stubinclude
// for Thread Debug purposes
void hal_get_gdb_registers(CYG_ADDRWORD *dest, HAL_SavedRegisters * s)
{
GDB_SavedRegisters *d = (GDB_SavedRegisters *)dest;
d->eax = s->eax;
d->ebx = s->ebx;
d->ecx = s->ecx;
d->edx = s->edx;
d->ebp = s->ebp;
d->esp = s->esp;
d->edi = s->edi;
d->esi = s->esi;
d->pc = s->pc;
d->cs = s->cs;
d->ps = s->eflags;
d->ss = 0;
asm volatile ("movw %%ss,%0\n" :"=m" (d->ss));
d->ds = 0;
asm volatile ("movw %%ds,%0\n" :"=m" (d->ds));
d->es = 0;
asm volatile ("movw %%es,%0\n" :"=m" (d->es));
d->fs = 0;
asm volatile ("movw %%fs,%0\n" :"=m" (d->fs));
d->gs = 0;
asm volatile ("movw %%gs,%0\n" :"=m" (d->gs));
#ifdef CYGHWR_HAL_I386_FPU
#ifdef CYGHWR_HAL_I386_FPU_SWITCH_LAZY
asm volatile ("fnop\n"); // force state save
local_memcpy(&d->fcw, &s->fpucontext->fpstate[0], sizeof(s->fpucontext->fpstate));
#ifdef CYGHWR_HAL_I386_PENTIUM_SSE
local_memcpy(&d->xmm0[0], &s->fpucontext->xmm0[0], (16 * 8) + 4);
#endif
#else
local_memcpy(&d->fcw, &s->fpucontext.fpstate[0], sizeof(s->fpucontext.fpstate));
#ifdef CYGHWR_HAL_I386_PENTIUM_SSE
local_memcpy(&d->xmm0[0], &s->fpucontext.xmm0[0], (16 * 8) + 4);
#endif
#endif
#endif
#ifdef CYGHWR_HAL_I386_PENTIUM_GDB_REGS
{
unsigned long val;
asm volatile ("movl %%cr0,%0\n"
"movl %0,%1\n"
: "=r" (val), "=m" (d->cr0));
asm volatile ("movl %%cr2,%0\n"
"movl %0,%1\n"
: "=r" (val), "=m" (d->cr2));
asm volatile ("movl %%cr3,%0\n"
"movl %0,%1\n"
: "=r" (val), "=m" (d->cr3));
asm volatile ("movl %%cr4,%0\n"
"movl %0,%1\n"
: "=r" (val), "=m" (d->cr4));
asm volatile ("sgdt %0\n" :"=m" (d->gdtr));
asm volatile ("sidt %0\n" :"=m" (d->idtr));
}
#endif // CYGHWR_HAL_I386_PENTIUM_GDB_REGS
}
void hal_set_gdb_registers(HAL_SavedRegisters * d, CYG_ADDRWORD * src)
{
GDB_SavedRegisters *s = (GDB_SavedRegisters *)src;
d->eax = s->eax;
d->ebx = s->ebx;
d->ecx = s->ecx;
d->edx = s->edx;
d->ebp = s->ebp;
d->esp = s->esp;
d->edi = s->edi;
d->esi = s->esi;
d->pc = s->pc;
d->cs = s->cs;
d->eflags = s->ps;
#ifdef CYGHWR_HAL_I386_FPU
#ifdef CYGHWR_HAL_I386_FPU_SWITCH_LAZY
local_memcpy(&d->fpucontext->fpstate[0], &s->fcw, sizeof(d->fpucontext->fpstate));
#ifdef CYGHWR_HAL_I386_PENTIUM_SSE
local_memcpy(&d->fpucontext->xmm0[0], &s->xmm0[0], (16 * 8) + 4);
#endif
#else
local_memcpy(&d->fpucontext.fpstate[0], &s->fcw, sizeof(d->fpucontext.fpstate));
#ifdef CYGHWR_HAL_I386_PENTIUM_SSE
local_memcpy(&d->fpucontext.xmm0[0], &s->xmm0[0], (16 * 8) + 4);
#endif
#endif
#endif
#ifdef CYGHWR_HAL_I386_PENTIUM_GDB_REGS
{
unsigned long val;
val = s->cr0;
asm volatile ("movl %0,%%cr0\n" : : "r" (val));
val = s->cr2;
asm volatile ("movl %0,%%cr2\n" : : "r" (val));
val = s->cr3;
asm volatile ("movl %0,%%cr3\n" : : "r" (val));
val = s->cr4;
asm volatile ("movl %0,%%cr4\n" : : "r" (val));
}
#endif // CYGHWR_HAL_I386_PENTIUM_GDB_REGS
}
//----------------------------------------------------------------------
// End
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -