/[qemu]/qemu/softmmu_template.h
ViewVC logotype

Diff of /qemu/softmmu_template.h

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

revision 1.3 by bellard, Wed Aug 20 23:02:09 2003 UTC revision 1.4 by bellard, Mon Oct 27 21:22:22 2003 UTC
# Line 21  Line 21 
21    
22  #if DATA_SIZE == 8  #if DATA_SIZE == 8
23  #define SUFFIX q  #define SUFFIX q
24    #define USUFFIX q
25  #define DATA_TYPE uint64_t  #define DATA_TYPE uint64_t
26  #elif DATA_SIZE == 4  #elif DATA_SIZE == 4
27  #define SUFFIX l  #define SUFFIX l
28    #define USUFFIX l
29  #define DATA_TYPE uint32_t  #define DATA_TYPE uint32_t
30  #elif DATA_SIZE == 2  #elif DATA_SIZE == 2
31  #define SUFFIX w  #define SUFFIX w
32    #define USUFFIX uw
33  #define DATA_TYPE uint16_t  #define DATA_TYPE uint16_t
34  #elif DATA_SIZE == 1  #elif DATA_SIZE == 1
35  #define SUFFIX b  #define SUFFIX b
36    #define USUFFIX ub
37  #define DATA_TYPE uint8_t  #define DATA_TYPE uint8_t
38  #else  #else
39  #error unsupported data size  #error unsupported data size
40  #endif  #endif
41    
42  static DATA_TYPE glue(slow_ld, SUFFIX)(unsigned long addr, void *retaddr);  static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(unsigned long addr,
43  static void glue(slow_st, SUFFIX)(unsigned long addr, DATA_TYPE val,                                                          int is_user,
44                                    void *retaddr);                                                          void *retaddr);
45    static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(unsigned long addr,
46                                                       DATA_TYPE val,
47                                                       int is_user,
48                                                       void *retaddr);
49    
50  static inline DATA_TYPE glue(io_read, SUFFIX)(unsigned long physaddr,  static inline DATA_TYPE glue(io_read, SUFFIX)(unsigned long physaddr,
51                                                unsigned long tlb_addr)                                                unsigned long tlb_addr)
# Line 81  static inline void glue(io_write, SUFFIX Line 89  static inline void glue(io_write, SUFFIX
89  }  }
90    
91  /* handle all cases except unaligned access which span two pages */  /* handle all cases except unaligned access which span two pages */
92  DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), _mmu)(unsigned long addr)  DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(unsigned long addr,
93                                                             int is_user)
94  {  {
95      DATA_TYPE res;      DATA_TYPE res;
96      int is_user, index;      int index;
97      unsigned long physaddr, tlb_addr;      unsigned long physaddr, tlb_addr;
98      void *retaddr;      void *retaddr;
99            
100      /* test if there is match for unaligned or IO access */      /* test if there is match for unaligned or IO access */
101      /* XXX: could done more in memory macro in a non portable way */      /* XXX: could done more in memory macro in a non portable way */
     is_user = ((env->hflags & HF_CPL_MASK) == 3);  
102      index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);      index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
103   redo:   redo:
104      tlb_addr = env->tlb_read[is_user][index].address;      tlb_addr = env->tlb_read[is_user][index].address;
# Line 104  DATA_TYPE REGPARM(1) glue(glue(__ld, SUF Line 112  DATA_TYPE REGPARM(1) glue(glue(__ld, SUF
112          } else if (((addr & 0xfff) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {          } else if (((addr & 0xfff) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
113              /* slow unaligned access (it spans two pages or IO) */              /* slow unaligned access (it spans two pages or IO) */
114          do_unaligned_access:          do_unaligned_access:
115              retaddr = __builtin_return_address(0);              retaddr = GETPC();
116              res = glue(slow_ld, SUFFIX)(addr, retaddr);              res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr,
117                                                             is_user, retaddr);
118          } else {          } else {
119              /* unaligned access in the same page */              /* unaligned access in the same page */
120              res = glue(glue(ldu, SUFFIX), _raw)((uint8_t *)physaddr);              res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
121          }          }
122      } else {      } else {
123          /* the page is not in the TLB : fill it */          /* the page is not in the TLB : fill it */
124          retaddr = __builtin_return_address(0);          retaddr = GETPC();
125          tlb_fill(addr, 0, retaddr);          tlb_fill(addr, 0, is_user, retaddr);
126          goto redo;          goto redo;
127      }      }
128      return res;      return res;
129  }  }
130    
131  /* handle all unaligned cases */  /* handle all unaligned cases */
132  static DATA_TYPE glue(slow_ld, SUFFIX)(unsigned long addr, void *retaddr)  static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(unsigned long addr,
133                                                            int is_user,
134                                                            void *retaddr)
135  {  {
136      DATA_TYPE res, res1, res2;      DATA_TYPE res, res1, res2;
137      int is_user, index, shift;      int index, shift;
138      unsigned long physaddr, tlb_addr, addr1, addr2;      unsigned long physaddr, tlb_addr, addr1, addr2;
139    
     is_user = ((env->hflags & HF_CPL_MASK) == 3);  
140      index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);      index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
141   redo:   redo:
142      tlb_addr = env->tlb_read[is_user][index].address;      tlb_addr = env->tlb_read[is_user][index].address;
# Line 142  static DATA_TYPE glue(slow_ld, SUFFIX)(u Line 152  static DATA_TYPE glue(slow_ld, SUFFIX)(u
152              /* slow unaligned access (it spans two pages) */              /* slow unaligned access (it spans two pages) */
153              addr1 = addr & ~(DATA_SIZE - 1);              addr1 = addr & ~(DATA_SIZE - 1);
154              addr2 = addr1 + DATA_SIZE;              addr2 = addr1 + DATA_SIZE;
155              res1 = glue(slow_ld, SUFFIX)(addr1, retaddr);              res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr1,
156              res2 = glue(slow_ld, SUFFIX)(addr2, retaddr);                                                            is_user, retaddr);
157                res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr2,
158                                                              is_user, retaddr);
159              shift = (addr & (DATA_SIZE - 1)) * 8;              shift = (addr & (DATA_SIZE - 1)) * 8;
160  #ifdef TARGET_WORDS_BIGENDIAN  #ifdef TARGET_WORDS_BIGENDIAN
161              res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift));              res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift));
# Line 152  static DATA_TYPE glue(slow_ld, SUFFIX)(u Line 164  static DATA_TYPE glue(slow_ld, SUFFIX)(u
164  #endif  #endif
165          } else {          } else {
166              /* unaligned/aligned access in the same page */              /* unaligned/aligned access in the same page */
167              res = glue(glue(ldu, SUFFIX), _raw)((uint8_t *)physaddr);              res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
168          }          }
169      } else {      } else {
170          /* the page is not in the TLB : fill it */          /* the page is not in the TLB : fill it */
171          tlb_fill(addr, 0, retaddr);          tlb_fill(addr, 0, is_user, retaddr);
172          goto redo;          goto redo;
173      }      }
174      return res;      return res;
175  }  }
176    
177    
178  void REGPARM(2) glue(glue(__st, SUFFIX), _mmu)(unsigned long addr, DATA_TYPE val)  void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(unsigned long addr,
179                                                        DATA_TYPE val,
180                                                        int is_user)
181  {  {
182      unsigned long physaddr, tlb_addr;      unsigned long physaddr, tlb_addr;
183      void *retaddr;      void *retaddr;
184      int is_user, index;      int index;
185            
     is_user = ((env->hflags & HF_CPL_MASK) == 3);  
186      index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);      index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
187   redo:   redo:
188      tlb_addr = env->tlb_write[is_user][index].address;      tlb_addr = env->tlb_write[is_user][index].address;
# Line 182  void REGPARM(2) glue(glue(__st, SUFFIX), Line 195  void REGPARM(2) glue(glue(__st, SUFFIX),
195              glue(io_write, SUFFIX)(physaddr, val, tlb_addr);              glue(io_write, SUFFIX)(physaddr, val, tlb_addr);
196          } else if (((addr & 0xfff) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {          } else if (((addr & 0xfff) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
197          do_unaligned_access:          do_unaligned_access:
198              retaddr = __builtin_return_address(0);              retaddr = GETPC();
199              glue(slow_st, SUFFIX)(addr, val, retaddr);              glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val,
200                                                       is_user, retaddr);
201          } else {          } else {
202              /* aligned/unaligned access in the same page */              /* aligned/unaligned access in the same page */
203              glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, val);              glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, val);
204          }          }
205      } else {      } else {
206          /* the page is not in the TLB : fill it */          /* the page is not in the TLB : fill it */
207          retaddr = __builtin_return_address(0);          retaddr = GETPC();
208          tlb_fill(addr, 1, retaddr);          tlb_fill(addr, 1, is_user, retaddr);
209          goto redo;          goto redo;
210      }      }
211  }  }
212    
213  /* handles all unaligned cases */  /* handles all unaligned cases */
214  static void glue(slow_st, SUFFIX)(unsigned long addr, DATA_TYPE val,  static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(unsigned long addr,
215                                    void *retaddr)                                                     DATA_TYPE val,
216                                                       int is_user,
217                                                       void *retaddr)
218  {  {
219      unsigned long physaddr, tlb_addr;      unsigned long physaddr, tlb_addr;
220      int is_user, index, i;      int index, i;
221    
     is_user = ((env->hflags & HF_CPL_MASK) == 3);  
222      index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);      index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
223   redo:   redo:
224      tlb_addr = env->tlb_write[is_user][index].address;      tlb_addr = env->tlb_write[is_user][index].address;
# Line 219  static void glue(slow_st, SUFFIX)(unsign Line 234  static void glue(slow_st, SUFFIX)(unsign
234              /* XXX: not efficient, but simple */              /* XXX: not efficient, but simple */
235              for(i = 0;i < DATA_SIZE; i++) {              for(i = 0;i < DATA_SIZE; i++) {
236  #ifdef TARGET_WORDS_BIGENDIAN  #ifdef TARGET_WORDS_BIGENDIAN
237                  slow_stb(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)), retaddr);                  glue(slow_stb, MMUSUFFIX)(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)),
238                                              is_user, retaddr);
239  #else  #else
240                  slow_stb(addr + i, val >> (i * 8), retaddr);                  glue(slow_stb, MMUSUFFIX)(addr + i, val >> (i * 8),
241                                              is_user, retaddr);
242  #endif  #endif
243              }              }
244          } else {          } else {
# Line 230  static void glue(slow_st, SUFFIX)(unsign Line 247  static void glue(slow_st, SUFFIX)(unsign
247          }          }
248      } else {      } else {
249          /* the page is not in the TLB : fill it */          /* the page is not in the TLB : fill it */
250          tlb_fill(addr, 1, retaddr);          tlb_fill(addr, 1, is_user, retaddr);
251          goto redo;          goto redo;
252      }      }
253  }  }
# Line 238  static void glue(slow_st, SUFFIX)(unsign Line 255  static void glue(slow_st, SUFFIX)(unsign
255  #undef SHIFT  #undef SHIFT
256  #undef DATA_TYPE  #undef DATA_TYPE
257  #undef SUFFIX  #undef SUFFIX
258    #undef USUFFIX
259  #undef DATA_SIZE  #undef DATA_SIZE

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

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