OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [i386/] [arch/] [v2_0/] [src/] [i386_stub.c] - Blame information for rev 27

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
/* i386_stub.c - helper functions for stub, generic to all i386 processors
2
 *
3
 * Copyright (c) 1998,1999, 2001 Cygnus Solutions
4
 *
5
 * The authors hereby grant permission to use, copy, modify, distribute,
6
 * and license this software and its documentation for any purpose, provided
7
 * that existing copyright notices are retained in all copies and that this
8
 * notice is included verbatim in any distributions. No written agreement,
9
 * license, or royalty fee is required for any of the authorized uses.
10
 * Modifications to this software may be copyrighted by their authors
11
 * and need not follow the licensing terms described here, provided that
12
 * the new terms are clearly indicated on the first page of each file where
13
 * they apply.
14
 */
15
 
16
/*
17
- pjo, 29 sep 1999
18
- Copied from the ARM configuration and merged with an older GDB i386-stub.c.
19
*/
20
 
21
#include <stddef.h>
22
 
23
#include <pkgconf/hal.h>
24
 
25
#ifdef CYGPKG_REDBOOT
26
#include <pkgconf/redboot.h>
27
#endif
28
 
29
#ifdef CYGPKG_HAL_I386_SIM
30
#error "GDB Stub support not implemented for i386 SIM"
31
#endif
32
 
33
#include <cyg/hal/hal_stub.h>
34
#include <cyg/hal/hal_arch.h>
35
#include <cyg/hal/hal_intr.h>
36
#include <cyg/hal/i386_stub.h>
37
 
38
#ifndef FALSE
39
#define FALSE 0
40
#define TRUE  1
41
#endif
42
 
43
#ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
44
#include <cyg/hal/dbg-threads-api.h>    // dbg_currthread_id
45
#endif
46
 
47
// We need a local memcpy so we don't rely on libc.
48
static inline void*
49
memcpy(void* dest, void* src, int size)
50
{
51
    unsigned char* __d = (unsigned char*) dest;
52
    unsigned char* __s = (unsigned char*) src;
53
 
54
    while(size--)
55
        *__d++ = *__s++;
56
 
57
    return dest;
58
}
59
 
60
 
61
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
62
 
63
/* Given a trap value TRAP, return the corresponding signal. */
64
 
65
int __computeSignal (unsigned int trap_number)
66
{
67
    switch (trap_number)
68
        {
69
                case CYGNUM_HAL_VECTOR_DIV0:
70
                        /* This isn't quite accurrate: this is integer division only. */
71
                        return SIGFPE ;
72
 
73
                case CYGNUM_HAL_VECTOR_DEBUG:
74
                        return SIGTRAP ;
75
 
76
                case CYGNUM_HAL_VECTOR_NMI:
77
                        return SIGINT ;
78
 
79
                case CYGNUM_HAL_VECTOR_BREAKPOINT:
80
                        return SIGTRAP ;
81
 
82
                case CYGNUM_HAL_VECTOR_OVERFLOW:
83
                case CYGNUM_HAL_VECTOR_BOUND:
84
                        return SIGSEGV ;
85
 
86
                case CYGNUM_HAL_VECTOR_OPCODE:
87
                        return SIGILL ;
88
 
89
                case CYGNUM_HAL_VECTOR_NO_DEVICE:
90
                case CYGNUM_HAL_VECTOR_FPE:
91
                        return SIGFPE ;
92
 
93
                case CYGNUM_HAL_VECTOR_DOUBLE_FAULT:
94
                        return SIGTRAP ;
95
 
96
                case CYGNUM_HAL_VECTOR_INVALID_TSS:
97
                case CYGNUM_HAL_VECTOR_SEGV:
98
                case CYGNUM_HAL_VECTOR_STACK_FAULT:
99
                case CYGNUM_HAL_VECTOR_PROTECTION:
100
                case CYGNUM_HAL_VECTOR_PAGE:
101
                case CYGNUM_HAL_VECTOR_ALIGNMENT:
102
                        return SIGSEGV ;
103
 
104
                default:
105
                        return SIGTRAP;
106
    }
107
}
108
 
109
 
110
/* Return the trap number corresponding to the last-taken trap. */
111
 
112
int __get_trap_number (void)
113
{
114
#if 1
115
    // The vector is not not part of the GDB register set so get it
116
    // directly from the HAL saved context.
117
    return _hal_registers->vector;
118
#else
119
        extern int hal_pc_trap_number ;
120
    // The vector is not not part of the GDB register set so get it
121
    // directly from the save context.
122
    return hal_pc_trap_number ;
123
#endif        
124
}
125
 
126
#if defined(CYGSEM_REDBOOT_BSP_SYSCALLS)
127
int __is_bsp_syscall(void)
128
{
129
    return __get_trap_number() == 0x80;
130
}
131
#endif
132
 
133
/* Set the currently-saved pc register value to PC. */
134
 
135
void set_pc (target_register_t pc)
136
{
137
    put_register (PC, pc);
138
}
139
 
140
static target_register_t
141
reg_offset(regnames_t reg)
142
{
143
    switch(reg) {
144
      case EAX ... GS:
145
        return reg * 4;
146
#ifdef CYGHWR_HAL_I386_FPU
147
      case REG_FST0 ... REG_FST7:
148
        return (target_register_t)&((GDB_SavedRegisters *)0)->st0[0]
149
            + ((reg - REG_FST0) * 10);
150
      case REG_FCTRL:
151
        return (target_register_t)&((GDB_SavedRegisters *)0)->fcw;
152
      case REG_FSTAT:
153
        return (target_register_t)&((GDB_SavedRegisters *)0)->fsw;
154
      case REG_FTAG:
155
        return (target_register_t)&((GDB_SavedRegisters *)0)->ftw;
156
      case REG_FISEG:
157
      case REG_FOP:
158
        // REG_FISEG is lsw, REG_FOP is msw
159
        return (target_register_t)&((GDB_SavedRegisters *)0)->cssel;
160
      case REG_FIOFF:
161
        return (target_register_t)&((GDB_SavedRegisters *)0)->ipoff;
162
      case REG_FOSEG:
163
        return (target_register_t)&((GDB_SavedRegisters *)0)->opsel;
164
      case REG_FOOFF:
165
        return (target_register_t)&((GDB_SavedRegisters *)0)->dataoff;
166
#endif
167
#if 0  // GDB never asks for MMX regs directly, but it did...
168
      case REG_MMX0 ... REG_MMX7:
169
          {
170
              target_register_t tos = (get_register (REG_FSTAT) >> 11) & 7;
171
              return reg_offset((((8 - tos) + reg - REG_MMX0) & 7) + REG_FST0);
172
          }
173
#endif
174
#ifdef CYGHWR_HAL_I386_PENTIUM_SSE
175
      case REG_XMM0 ... REG_XMM7:
176
        return (target_register_t)&((GDB_SavedRegisters *)0)->xmm0[0]
177
            + ((reg - REG_XMM0) * 16);
178
      case REG_MXCSR:
179
        return (target_register_t)&((GDB_SavedRegisters *)0)->mxcsr;
180
#endif
181
#ifdef CYGHWR_HAL_I386_PENTIUM_GDB_REGS
182
      case REG_CR0 ... REG_CR4:
183
        return (target_register_t)&((GDB_SavedRegisters *)0)->cr0
184
            + ((reg - REG_CR0) * 4);
185
      case REG_GDT:
186
        return (target_register_t)&((GDB_SavedRegisters *)0)->gdtr[0];
187
      case REG_IDT:
188
        return (target_register_t)&((GDB_SavedRegisters *)0)->idtr[0];
189
#endif
190
      default:
191
        return -1;
192
    }
193
    return -1;
194
}
195
 
196
 
197
// Return the currently-saved value corresponding to register REG of
198
// the exception context.
199
target_register_t
200
get_register (regnames_t reg)
201
{
202
    target_register_t val;
203
    target_register_t offset = reg_offset(reg);
204
 
205
    if (REGSIZE(reg) > sizeof(target_register_t) || offset == -1)
206
        return -1;
207
 
208
    val = _registers[offset/sizeof(target_register_t)];
209
 
210
#ifdef CYGHWR_HAL_I386_FPU
211
    if (reg == REG_FISEG)
212
        val &= 0xffff;
213
    else if (reg == REG_FOP)
214
        val = (val >> 16) & 0xffff;
215
#endif
216
 
217
    return val;
218
}
219
 
220
// Store VALUE in the register corresponding to WHICH in the exception
221
// context.
222
void
223
put_register (regnames_t which, target_register_t value)
224
{
225
    target_register_t index;
226
    target_register_t offset = reg_offset(which);
227
 
228
    if (REGSIZE(which) > sizeof(target_register_t) || offset == -1)
229
        return;
230
 
231
    index = offset / sizeof(target_register_t);
232
 
233
    switch (which) {
234
#ifdef CYGHWR_HAL_I386_FPU
235
      case REG_FISEG:
236
        value = (_registers[index] & 0xffff0000) | (value & 0xffff);
237
        break;
238
      case REG_FOP:
239
        value = (_registers[index] & 0x0000ffff) | (value << 16);
240
        break;
241
#endif
242
#ifdef CYGHWR_HAL_I386_PENTIUM_GDB_REGS
243
      case REG_CR0:
244
        value &= REG_CR0_MASK;
245
        break;
246
      case REG_CR2:
247
        value &= REG_CR2_MASK;
248
        break;
249
      case REG_CR3:
250
        value &= REG_CR3_MASK;
251
        break;
252
      case REG_CR4:
253
        value &= REG_CR4_MASK;
254
        break;
255
#endif
256
      default:
257
        break;
258
    }
259
    _registers[index] = value;
260
}
261
 
262
#ifdef CYGHWR_HAL_I386_PENTIUM_GDB_REGS
263
// Handle the Model Specific Registers
264
static target_register_t _msrval[2];
265
static int _which_msr = 0;
266
static int _dummy_flag = 0;
267
 
268
extern void * volatile __mem_fault_handler;
269
 
270
static void
271
__do_read_msr (void)
272
{
273
    // _dummy_flag is always false but the goto is necessary to keep
274
    // some compilers from reordering stuff across the 'err' label.
275
    if (_dummy_flag)
276
        goto err;
277
 
278
    __mem_fault = 1;                      // Defaults to 'fail'. Is cleared
279
                                          // when the wrmsr completes.
280
    __mem_fault_handler = &&err;
281
 
282
    asm volatile ("movl %2,%%ecx\n"
283
                  "rdmsr\n"
284
                  "movl %%edx,%1\n"
285
                  "movl %%eax,%0\n"
286
                  : "=m" (_msrval[0]), "=m" (_msrval[1])
287
                  : "m" (_which_msr)
288
                  : "ecx", "ebx", "edx", "eax", "memory");
289
 
290
    __mem_fault = 0;
291
 
292
 err:
293
    __mem_fault_handler = (void *)0;
294
}
295
 
296
static void
297
__do_write_msr (void)
298
{
299
    // _dummy_flag is always false but the goto is necessary to keep
300
    // some compilers from reordering stuff across the 'err' label.
301
    if (_dummy_flag)
302
        goto err;
303
 
304
    __mem_fault = 1;                      // Defaults to 'fail'. Is cleared
305
                                          // when the wrmsr completes.
306
    __mem_fault_handler = &&err;
307
 
308
    asm volatile ("movl %1,%%edx\n"
309
                  "movl %0,%%eax\n"
310
                  "movl %2,%%ecx\n"
311
                  "wrmsr\n"
312
                  : /* no outputs */
313
                  : "m" (_msrval[0]), "m" (_msrval[1]), "m" (_which_msr)
314
                  : "ecx", "ebx", "edx", "eax", "memory");
315
 
316
    __mem_fault = 0;
317
 
318
 err:
319
    __mem_fault_handler = (void *)0;
320
}
321
 
322
static int
323
rdmsr (int msrnum, target_register_t *msrval)
324
{
325
    _which_msr = msrnum;
326
    __set_mem_fault_trap (__do_read_msr);
327
    if (__mem_fault)
328
        return 0;
329
 
330
    msrval[0] = _msrval[0];
331
    msrval[1] = _msrval[1];
332
    return 1;
333
}
334
 
335
static int
336
wrmsr (int msrnum, target_register_t *msrval)
337
{
338
    _which_msr = msrnum;
339
    _msrval[0] = msrval[0];
340
    _msrval[1] = msrval[1];
341
 
342
    __set_mem_fault_trap (__do_write_msr);
343
    if (__mem_fault)
344
        return 0;
345
 
346
    return 1;
347
}
348
 
349
int
350
cyg_hal_stub_process_query (char *pkt, char *buf, int bufsize)
351
{
352
    unsigned long val1, val2, val3, val4;
353
    int i = 0, max_input = 0;
354
 
355
    if ('C' == pkt[0] &&
356
        'P' == pkt[1] &&
357
        'U' == pkt[2] &&
358
        'I' == pkt[3] &&
359
        'D' == pkt[4]) {
360
 
361
        for (i = 0; i <= max_input; i++) {
362
 
363
            asm volatile ("movl %4,%%eax\n"
364
                          "cpuid\n"
365
                          "movl %%eax,%0\n"
366
                          "movl %%ebx,%1\n"
367
                          "movl %%ecx,%2\n"
368
                          "movl %%edx,%3\n"
369
                          : "=m" (val1), "=m" (val2), "=m" (val3), "=m" (val4)
370
                          : "m" (i)
371
                          : "eax", "ebx", "ecx", "edx", "memory");
372
 
373
            /*
374
             * get the max value to use to get all the CPUID info.
375
             */
376
            if (i == 0)
377
                max_input = val1;
378
 
379
            /*
380
             * Swap the bytes around to handle endianness conversion:
381
             * ie 12345678 --> 78563412
382
             */
383
            val1 = (((val1 & 0x000000ff) << 24) | ((val1 & 0x0000ff00) <<  8) |
384
                    ((val1 & 0x00ff0000) >>  8) | ((val1 & 0xff000000) >> 24));
385
            val2 = (((val2 & 0x000000ff) << 24) | ((val2 & 0x0000ff00) <<  8) |
386
                    ((val2 & 0x00ff0000) >>  8) | ((val2 & 0xff000000) >> 24));
387
            val3 = (((val3 & 0x000000ff) << 24) | ((val3 & 0x0000ff00) <<  8) |
388
                    ((val3 & 0x00ff0000) >>  8) | ((val3 & 0xff000000) >> 24));
389
            val4 = (((val4 & 0x000000ff) << 24) | ((val4 & 0x0000ff00) <<  8) |
390
                    ((val4 & 0x00ff0000) >>  8) | ((val4 & 0xff000000) >> 24));
391
 
392
            /*
393
             * Generate the packet
394
             */
395
            __mem2hex ((char *)&val1, buf, 8, 0);  buf[8] = ',';  buf += 9;
396
            __mem2hex ((char *)&val2, buf, 8, 0);  buf[8] = ',';  buf += 9;
397
            __mem2hex ((char *)&val3, buf, 8, 0);  buf[8] = ',';  buf += 9;
398
            __mem2hex ((char *)&val4, buf, 8, 0);  buf[8] = ';';  buf += 9;
399
        }
400
 
401
        /*
402
         * The packet is complete.  buf points just past the final semicolon.
403
         * Remove that semicolon and properly terminate the packet.
404
         */
405
        *(buf - 1) = '\0';
406
 
407
        return 1;
408
    }
409
 
410
    if ('M' == pkt[0] &&
411
        'S' == pkt[1] &&
412
        'R' == pkt[2]) {
413
 
414
        pkt += 4;
415
        if (__hexToInt (&pkt, &val1)) {
416
            target_register_t msrval[2];
417
 
418
            // rdmsr implicitly sets _which_msr for subsequent REG_MSR read/write.
419
            if (rdmsr(val1, msrval))
420
                __mem2hex ((char*)msrval, buf, 8, 0);
421
            else
422
                memcpy (buf, "INVALID", 8);
423
        }
424
        return 1;
425
    }
426
 
427
    return 0;
428
}
429
#endif // CYGHWR_HAL_I386_PENTIUM_GDB_REGS
430
 
431
// Write the contents of register WHICH into VALUE as raw bytes. We
432
// only support this for the MMX, FPU, and SSE registers.
433
// Return true if it is a valid register.
434
int
435
get_register_as_bytes (regnames_t which, char *value)
436
{
437
    target_register_t offset;
438
 
439
#ifdef CYGHWR_HAL_I386_PENTIUM_GDB_REGS
440
    // Read the currently selected MSR
441
    if (which == REG_MSR) {
442
        if (rdmsr(_which_msr, _msrval)) {
443
            memcpy (value, _msrval, REGSIZE(which));
444
            return 1;
445
        }
446
        return 0;
447
    }
448
    // We can't actually read the LDT or TR in software, so just return invalid.
449
    if (which == REG_LDT || which == REG_TR)
450
        return 0;
451
 
452
    if (which == REG_GDT || which == REG_IDT) {
453
        // GDB requires these to be sent base first though the CPU stores them
454
        // limit first in 6 bytes. Weird.
455
        offset = reg_offset(which);
456
        memcpy (value, (char *)_registers + offset + 2, 4);
457
        memcpy (value + 4, (char *)_registers + offset, 2);
458
        return 1;
459
    }
460
#endif
461
 
462
    offset = reg_offset(which);
463
    if (offset != -1) {
464
        memcpy (value, (char *)_registers + offset, REGSIZE(which));
465
        return 1;
466
    }
467
    return 0;
468
}
469
 
470
// Alter the contents of saved register WHICH to contain VALUE.  We only
471
// support this for the MMX, FPU, and SSE registers.
472
int
473
put_register_as_bytes (regnames_t which, char *value)
474
{
475
    target_register_t offset;
476
 
477
#ifdef CYGHWR_HAL_I386_PENTIUM_GDB_REGS
478
    // Write the currently selected MSR
479
    if (which == REG_MSR)
480
        return wrmsr(_which_msr, (target_register_t*)value);
481
 
482
    // We can't actually write the LDT OR TR in software, so just return invalid.
483
    if (which == REG_LDT || which == REG_TR)
484
        return 0;
485
    if (which == REG_GDT || which == REG_IDT) {
486
        // GDB sends these base first, though the CPU stores them
487
        // limit first. Weird.
488
        offset = reg_offset(which);
489
        memcpy ((char *)_registers + offset + 2, value, 4);
490
        memcpy ((char *)_registers + offset, value + 4, 2);
491
        return 1;
492
    }
493
#endif
494
 
495
    offset = reg_offset(which);
496
    if (offset != -1) {
497
        memcpy ((char *)_registers + offset, value, REGSIZE(which));
498
        return 1;
499
    }
500
    return 0;
501
}
502
 
503
/*----------------------------------------------------------------------
504
 * Single-step support
505
 */
506
 
507
/* Set things up so that the next user resume will execute one instruction.
508
   This may be done by setting breakpoints or setting a single step flag
509
   in the saved user registers, for example. */
510
 
511
 
512
/* We just turn on the trap bit in the flags register for the particular
513
        thread.  When it resumes, we'll get another debugger trap.
514
*/
515
void __single_step (void)
516
{       put_register(PS, get_register(PS) | PS_T) ;
517
}
518
 
519
/* Clear the single-step state. */
520
 
521
void __clear_single_step (void)
522
{       put_register(PS, get_register(PS) & ~PS_T) ;
523
}
524
 
525
void __install_breakpoints (void)
526
{
527
//    FIXME();
528
}
529
 
530
void __clear_breakpoints (void)
531
{
532
    __clear_breakpoint_list();
533
}
534
 
535
/* If the breakpoint we hit is in the breakpoint() instruction, return a
536
   non-zero value. */
537
 
538
int isBreakpointFunction ;
539
 
540
int
541
__is_breakpoint_function ()
542
{
543
    isBreakpointFunction = (get_register (PC) == (target_register_t)&_breakinst);
544
    return isBreakpointFunction ;
545
}
546
 
547
 
548
/* Skip the current instruction.  Since this is only called by the
549
   stub when the PC points to a breakpoint or trap instruction,
550
   we can safely just skip 4. */
551
 
552
void __skipinst (void)
553
{
554
//      FIXME() ;
555
}
556
 
557
#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
558
 
559
//----------------------------------------------------------------------
560
// We apparently need these function even when no stubinclude
561
// for Thread Debug purposes
562
 
563
 
564
void hal_get_gdb_registers(CYG_ADDRWORD *dest, HAL_SavedRegisters * s)
565
{
566
    GDB_SavedRegisters *d = (GDB_SavedRegisters *)dest;
567
 
568
    d->eax = s->eax;
569
    d->ebx = s->ebx;
570
    d->ecx = s->ecx;
571
    d->edx = s->edx;
572
    d->ebp = s->ebp;
573
    d->esp = s->esp;
574
    d->edi = s->edi;
575
    d->esi = s->esi;
576
    d->pc = s->pc;
577
    d->cs = s->cs;
578
    d->ps = s->eflags;
579
 
580
    d->ss = 0;
581
    asm volatile ("movw %%ss,%0\n" :"=m" (d->ss));
582
    d->ds = 0;
583
    asm volatile ("movw %%ds,%0\n" :"=m" (d->ds));
584
    d->es = 0;
585
    asm volatile ("movw %%es,%0\n" :"=m" (d->es));
586
    d->fs = 0;
587
    asm volatile ("movw %%fs,%0\n" :"=m" (d->fs));
588
    d->gs = 0;
589
    asm volatile ("movw %%gs,%0\n" :"=m" (d->gs));
590
 
591
#ifdef CYGHWR_HAL_I386_FPU
592
#ifdef CYGHWR_HAL_I386_FPU_SWITCH_LAZY
593
    asm volatile ("fnop\n");  // force state save
594
    memcpy(&d->fcw, &s->fpucontext->fpstate[0], sizeof(s->fpucontext->fpstate));
595
#ifdef CYGHWR_HAL_I386_PENTIUM_SSE
596
    memcpy(&d->xmm0[0], &s->fpucontext->xmm0[0], (16 * 8) + 4);
597
#endif
598
#else
599
    memcpy(&d->fcw, &s->fpucontext.fpstate[0], sizeof(s->fpucontext.fpstate));
600
#ifdef CYGHWR_HAL_I386_PENTIUM_SSE
601
    memcpy(&d->xmm0[0], &s->fpucontext.xmm0[0], (16 * 8) + 4);
602
#endif
603
#endif
604
#endif
605
 
606
#ifdef CYGHWR_HAL_I386_PENTIUM_GDB_REGS
607
    {
608
        unsigned long val;
609
 
610
        asm volatile ("movl %%cr0,%0\n"
611
                      "movl %0,%1\n"
612
                      : "=r" (val), "=m" (d->cr0));
613
        asm volatile ("movl %%cr2,%0\n"
614
                      "movl %0,%1\n"
615
                      : "=r" (val), "=m" (d->cr2));
616
        asm volatile ("movl %%cr3,%0\n"
617
                      "movl %0,%1\n"
618
                      : "=r" (val), "=m" (d->cr3));
619
        asm volatile ("movl %%cr4,%0\n"
620
                      "movl %0,%1\n"
621
                      : "=r" (val), "=m" (d->cr4));
622
        asm volatile ("sgdt %0\n" :"=m" (d->gdtr));
623
        asm volatile ("sidt %0\n" :"=m" (d->idtr));
624
    }
625
#endif // CYGHWR_HAL_I386_PENTIUM_GDB_REGS
626
}
627
 
628
void hal_set_gdb_registers(HAL_SavedRegisters * d, CYG_ADDRWORD * src)
629
{
630
    GDB_SavedRegisters *s = (GDB_SavedRegisters *)src;
631
 
632
    d->eax = s->eax;
633
    d->ebx = s->ebx;
634
    d->ecx = s->ecx;
635
    d->edx = s->edx;
636
    d->ebp = s->ebp;
637
    d->esp = s->esp;
638
    d->edi = s->edi;
639
    d->esi = s->esi;
640
    d->pc = s->pc;
641
    d->cs = s->cs;
642
    d->eflags = s->ps;
643
#ifdef CYGHWR_HAL_I386_FPU
644
#ifdef CYGHWR_HAL_I386_FPU_SWITCH_LAZY
645
    memcpy(&d->fpucontext->fpstate[0], &s->fcw, sizeof(d->fpucontext->fpstate));
646
#ifdef CYGHWR_HAL_I386_PENTIUM_SSE
647
    memcpy(&d->fpucontext->xmm0[0], &s->xmm0[0], (16 * 8) + 4);
648
#endif
649
#else
650
    memcpy(&d->fpucontext.fpstate[0], &s->fcw, sizeof(d->fpucontext.fpstate));
651
#ifdef CYGHWR_HAL_I386_PENTIUM_SSE
652
    memcpy(&d->fpucontext.xmm0[0], &s->xmm0[0], (16 * 8) + 4);
653
#endif
654
#endif
655
#endif
656
#ifdef CYGHWR_HAL_I386_PENTIUM_GDB_REGS
657
    {
658
        unsigned long val;
659
 
660
        val = s->cr0;
661
        asm volatile ("movl %0,%%cr0\n" : : "r" (val));
662
        val = s->cr2;
663
        asm volatile ("movl %0,%%cr2\n" : : "r" (val));
664
        val = s->cr3;
665
        asm volatile ("movl %0,%%cr3\n" : : "r" (val));
666
        val = s->cr4;
667
        asm volatile ("movl %0,%%cr4\n" : : "r" (val));
668
    }
669
#endif // CYGHWR_HAL_I386_PENTIUM_GDB_REGS
670
}
671
 
672
 
673
//----------------------------------------------------------------------
674
// End

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.