Revision 0ca790b9

b/cpu-i386.h
459 459
void page_set_flags(unsigned long start, unsigned long end, int flags);
460 460
void page_unprotect_range(uint8_t *data, unsigned long data_size);
461 461

  
462
/***************************************************/
463
/* internal functions */
464

  
465
#define GEN_FLAG_CODE32_SHIFT 0
466
#define GEN_FLAG_ADDSEG_SHIFT 1
467
#define GEN_FLAG_SS32_SHIFT   2
468
#define GEN_FLAG_VM_SHIFT     3
469
#define GEN_FLAG_ST_SHIFT     4
470
#define GEN_FLAG_CPL_SHIFT    7
471
#define GEN_FLAG_IOPL_SHIFT   9
472
#define GEN_FLAG_TF_SHIFT     11
473

  
474
int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, 
475
                     int *gen_code_size_ptr,
476
                     uint8_t *pc_start,  uint8_t *cs_base, int flags,
477
                     int *code_size_ptr);
478
void cpu_x86_tblocks_init(void);
479
void page_init(void);
480
int page_unprotect(unsigned long address);
481

  
482
#define CODE_GEN_MAX_SIZE        65536
483
#define CODE_GEN_ALIGN           16 /* must be >= of the size of a icache line */
484

  
485
#define CODE_GEN_HASH_BITS     15
486
#define CODE_GEN_HASH_SIZE     (1 << CODE_GEN_HASH_BITS)
487

  
488
/* maximum total translate dcode allocated */
489
#define CODE_GEN_BUFFER_SIZE     (2048 * 1024)
490
//#define CODE_GEN_BUFFER_SIZE     (128 * 1024)
491

  
492
typedef struct TranslationBlock {
493
    unsigned long pc;   /* simulated PC corresponding to this block (EIP + CS base) */
494
    unsigned long cs_base; /* CS base for this block */
495
    unsigned int flags; /* flags defining in which context the code was generated */
496
    uint16_t size;      /* size of target code for this block (1 <=
497
                           size <= TARGET_PAGE_SIZE) */
498
    uint8_t *tc_ptr;    /* pointer to the translated code */
499
    struct TranslationBlock *hash_next; /* next matching block */
500
    struct TranslationBlock *page_next[2]; /* next blocks in even/odd page */
501
} TranslationBlock;
502

  
503
static inline unsigned int tb_hash_func(unsigned long pc)
504
{
505
    return pc & (CODE_GEN_HASH_SIZE - 1);
506
}
507

  
508
void tb_flush(void);
509
TranslationBlock *tb_alloc(unsigned long pc, 
510
                           unsigned long size);
511

  
512
extern TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE];
513

  
514
extern uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE];
515
extern uint8_t *code_gen_ptr;
516

  
517
/* find a translation block in the translation cache. If not found,
518
   return NULL and the pointer to the last element of the list in pptb */
519
static inline TranslationBlock *tb_find(TranslationBlock ***pptb,
520
                                        unsigned long pc, 
521
                                        unsigned long cs_base,
522
                                        unsigned int flags)
523
{
524
    TranslationBlock **ptb, *tb;
525
    unsigned int h;
526
 
527
    h = tb_hash_func(pc);
528
    ptb = &tb_hash[h];
529
    for(;;) {
530
        tb = *ptb;
531
        if (!tb)
532
            break;
533
        if (tb->pc == pc && tb->cs_base == cs_base && tb->flags == flags)
534
            return tb;
535
        ptb = &tb->hash_next;
536
    }
537
    *pptb = ptb;
538
    return NULL;
539
}
540

  
541
#ifndef offsetof
542
#define offsetof(type, field) ((size_t) &((type *)0)->field)
543
#endif
544

  
545
#ifdef __powerpc__
546
static inline int testandset (int *p)
547
{
548
    int ret;
549
    __asm__ __volatile__ (
550
                          "0:    lwarx %0,0,%1 ;"
551
                          "      xor. %0,%3,%0;"
552
                          "      bne 1f;"
553
                          "      stwcx. %2,0,%1;"
554
                          "      bne- 0b;"
555
                          "1:    "
556
                          : "=&r" (ret)
557
                          : "r" (p), "r" (1), "r" (0)
558
                          : "cr0", "memory");
559
    return ret;
560
}
561
#endif
562

  
563
#ifdef __i386__
564
static inline int testandset (int *p)
565
{
566
    char ret;
567
    long int readval;
568
    
569
    __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
570
                          : "=q" (ret), "=m" (*p), "=a" (readval)
571
                          : "r" (1), "m" (*p), "a" (0)
572
                          : "memory");
573
    return ret;
574
}
575
#endif
576

  
577
#ifdef __s390__
578
static inline int testandset (int *p)
579
{
580
    int ret;
581

  
582
    __asm__ __volatile__ ("0: cs    %0,%1,0(%2)\n"
583
			  "   jl    0b"
584
			  : "=&d" (ret)
585
			  : "r" (1), "a" (p), "0" (*p) 
586
			  : "cc", "memory" );
587
    return ret;
588
}
589
#endif
590

  
591
#ifdef __alpha__
592
int testandset (int *p)
593
{
594
    int ret;
595
    unsigned long one;
596

  
597
    __asm__ __volatile__ ("0:	mov 1,%2\n"
598
			  "	ldl_l %0,%1\n"
599
			  "	stl_c %2,%1\n"
600
			  "	beq %2,1f\n"
601
			  ".subsection 2\n"
602
			  "1:	br 0b\n"
603
			  ".previous"
604
			  : "=r" (ret), "=m" (*p), "=r" (one)
605
			  : "m" (*p));
606
    return ret;
607
}
608
#endif
609

  
610
#ifdef __sparc__
611
static inline int testandset (int *p)
612
{
613
	int ret;
614

  
615
	__asm__ __volatile__("ldstub	[%1], %0"
616
			     : "=r" (ret)
617
			     : "r" (p)
618
			     : "memory");
619

  
620
	return (ret ? 1 : 0);
621
}
622
#endif
623

  
624
typedef int spinlock_t;
625

  
626
#define SPIN_LOCK_UNLOCKED 0
627

  
628
static inline void spin_lock(spinlock_t *lock)
629
{
630
    while (testandset(lock));
631
}
632

  
633
static inline void spin_unlock(spinlock_t *lock)
634
{
635
    *lock = 0;
636
}
637

  
638
static inline int spin_trylock(spinlock_t *lock)
639
{
640
    return !testandset(lock);
641
}
642

  
643
extern spinlock_t tb_lock;
644

  
645 462
#endif /* CPU_I386_H */

Also available in: Unified diff