/[qemu]/qemu/exec.c
ViewVC logotype

Diff of /qemu/exec.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.14 by bellard, Tue Jul 29 20:50:15 2003 UTC revision 1.15 by bellard, Sun Aug 10 21:47:01 2003 UTC
# Line 68  typedef struct PageDesc { Line 68  typedef struct PageDesc {
68  #define L2_SIZE (1 << L2_BITS)  #define L2_SIZE (1 << L2_BITS)
69    
70  static void tb_invalidate_page(unsigned long address);  static void tb_invalidate_page(unsigned long address);
71    static void io_mem_init(void);
72    
73  unsigned long real_host_page_size;  unsigned long real_host_page_size;
74  unsigned long host_page_bits;  unsigned long host_page_bits;
# Line 76  unsigned long host_page_mask; Line 77  unsigned long host_page_mask;
77    
78  static PageDesc *l1_map[L1_SIZE];  static PageDesc *l1_map[L1_SIZE];
79    
80    /* io memory support */
81    static unsigned long *l1_physmap[L1_SIZE];
82    CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
83    CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
84    static int io_mem_nb;
85    
86  static void page_init(void)  static void page_init(void)
87  {  {
88      /* NOTE: we can always suppose that host_page_size >=      /* NOTE: we can always suppose that host_page_size >=
# Line 201  void cpu_exec_init(void) Line 208  void cpu_exec_init(void)
208      if (!code_gen_ptr) {      if (!code_gen_ptr) {
209          code_gen_ptr = code_gen_buffer;          code_gen_ptr = code_gen_buffer;
210          page_init();          page_init();
211            io_mem_init();
212      }      }
213  }  }
214    
# Line 744  void page_unmap(void) Line 752  void page_unmap(void)
752      tb_flush();      tb_flush();
753  }  }
754  #endif  #endif
755    
756    void tlb_flush(CPUState *env)
757    {
758    #if defined(TARGET_I386)
759        int i;
760        for(i = 0; i < CPU_TLB_SIZE; i++) {
761            env->tlb_read[0][i].address = -1;
762            env->tlb_write[0][i].address = -1;
763            env->tlb_read[1][i].address = -1;
764            env->tlb_write[1][i].address = -1;
765        }
766    #endif
767    }
768    
769    void tlb_flush_page(CPUState *env, uint32_t addr)
770    {
771    #if defined(TARGET_I386)
772        int i;
773    
774        i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
775        env->tlb_read[0][i].address = -1;
776        env->tlb_write[0][i].address = -1;
777        env->tlb_read[1][i].address = -1;
778        env->tlb_write[1][i].address = -1;
779    #endif
780    }
781    
782    static inline unsigned long *physpage_find_alloc(unsigned int page)
783    {
784        unsigned long **lp, *p;
785        unsigned int index, i;
786    
787        index = page >> TARGET_PAGE_BITS;
788        lp = &l1_physmap[index >> L2_BITS];
789        p = *lp;
790        if (!p) {
791            /* allocate if not found */
792            p = malloc(sizeof(unsigned long) * L2_SIZE);
793            for(i = 0; i < L2_SIZE; i++)
794                p[i] = IO_MEM_UNASSIGNED;
795            *lp = p;
796        }
797        return p + (index & (L2_SIZE - 1));
798    }
799    
800    /* return NULL if no page defined (unused memory) */
801    unsigned long physpage_find(unsigned long page)
802    {
803        unsigned long *p;
804        unsigned int index;
805        index = page >> TARGET_PAGE_BITS;
806        p = l1_physmap[index >> L2_BITS];
807        if (!p)
808            return IO_MEM_UNASSIGNED;
809        return p[index & (L2_SIZE - 1)];
810    }
811    
812    /* register physical memory. 'size' must be a multiple of the target
813       page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
814       io memory page */
815    void cpu_register_physical_memory(unsigned long start_addr, unsigned long size,
816                                      long phys_offset)
817    {
818        unsigned long addr, end_addr;
819        unsigned long *p;
820    
821        end_addr = start_addr + size;
822        for(addr = start_addr; addr < end_addr; addr += TARGET_PAGE_SIZE) {
823            p = physpage_find_alloc(addr);
824            *p = phys_offset;
825            if ((phys_offset & ~TARGET_PAGE_MASK) == 0)
826                phys_offset += TARGET_PAGE_SIZE;
827        }
828    }
829    
830    static uint32_t unassigned_mem_readb(uint32_t addr)
831    {
832        return 0;
833    }
834    
835    static void unassigned_mem_writeb(uint32_t addr, uint32_t val)
836    {
837    }
838    
839    static CPUReadMemoryFunc *unassigned_mem_read[3] = {
840        unassigned_mem_readb,
841        unassigned_mem_readb,
842        unassigned_mem_readb,
843    };
844    
845    static CPUWriteMemoryFunc *unassigned_mem_write[3] = {
846        unassigned_mem_writeb,
847        unassigned_mem_writeb,
848        unassigned_mem_writeb,
849    };
850    
851    
852    static void io_mem_init(void)
853    {
854        io_mem_nb = 1;
855        cpu_register_io_memory(0, unassigned_mem_read, unassigned_mem_write);
856    }
857    
858    /* mem_read and mem_write are arrays of functions containing the
859       function to access byte (index 0), word (index 1) and dword (index
860       2). All functions must be supplied. If io_index is non zero, the
861       corresponding io zone is modified. If it is zero, a new io zone is
862       allocated. The return value can be used with
863       cpu_register_physical_memory(). (-1) is returned if error. */
864    int cpu_register_io_memory(int io_index,
865                               CPUReadMemoryFunc **mem_read,
866                               CPUWriteMemoryFunc **mem_write)
867    {
868        int i;
869    
870        if (io_index <= 0) {
871            if (io_index >= IO_MEM_NB_ENTRIES)
872                return -1;
873            io_index = io_mem_nb++;
874        } else {
875            if (io_index >= IO_MEM_NB_ENTRIES)
876                return -1;
877        }
878        
879        for(i = 0;i < 3; i++) {
880            io_mem_read[io_index][i] = mem_read[i];
881            io_mem_write[io_index][i] = mem_write[i];
882        }
883        return io_index << IO_MEM_SHIFT;
884    }

Legend:
Removed from v.1.14  
changed lines
  Added in v.1.15

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26