46 |
32 |
47 static const int access_mode[] = { |
33 static const int access_mode[] = { |
48 1, 2, 4, 8, 0 |
34 1, 2, 4, 8, 0 |
49 }; |
35 }; |
50 |
36 |
51 static const char *const access_tname[] = { |
37 static MemType data[32 * 8]; |
52 "\tverifying byte access mode...", |
38 static MemType cdata[32 * 8]; |
53 "\tverifying short access mode...", |
39 static MemType rdval[4]; |
54 "\tverifying word access mode...", |
40 |
55 "\tverifying long long access mode...", |
41 /* |
56 }; |
42 * efb_test_memory() |
|
43 * |
|
44 * This test will open the device and read and write to all memory |
|
45 * addresses. |
|
46 */ |
|
47 |
|
48 return_packet * |
|
49 efb_test_memory( |
|
50 register int const fd) |
|
51 { |
|
52 static return_packet rp; |
|
53 |
|
54 memset(&rp, 0, sizeof (return_packet)); |
|
55 |
|
56 if (gfx_vts_debug_mask & GRAPHICS_VTS_MEM_OFF) |
|
57 return (&rp); |
|
58 |
|
59 TraceMessage(VTS_DEBUG, "efb_test_memory", |
|
60 "efb_test_memory running\n"); |
|
61 |
|
62 efb_block_signals(); |
|
63 |
|
64 efb_lock_display(); |
|
65 |
|
66 memory_test(&rp, fd); |
|
67 |
|
68 efb_unlock_display(); |
|
69 |
|
70 efb_restore_signals(); |
|
71 |
|
72 TraceMessage(VTS_DEBUG, "efb_test_memory", |
|
73 "efb_test_memory completed\n"); |
|
74 |
|
75 return (&rp); |
|
76 } /* efb_test_memory() */ |
|
77 |
|
78 |
|
79 int |
|
80 memory_test( |
|
81 register return_packet *const rp, |
|
82 register int const fd) |
|
83 { |
|
84 register size_t i; |
|
85 register int signo; |
|
86 struct sigaction oldhup; |
|
87 struct sigaction oldint; |
|
88 struct sigaction oldalrm; |
|
89 struct sigaction oldterm; |
|
90 struct sigaction newsigact; |
|
91 sigset_t oldprocmask; |
|
92 |
|
93 memset(&efb_info, 0, sizeof (efb_info)); |
|
94 efb_info.efb_fd = fd; |
|
95 |
|
96 if (efb_map_mem(rp, GRAPHICS_ERR_MEMORY_MSG) != 0) |
|
97 return (-1); |
|
98 |
|
99 if (efb_init_info(rp, GRAPHICS_ERR_MEMORY_MSG) != 0) { |
|
100 efb_unmap_mem(NULL, GRAPHICS_ERR_MEMORY_MSG); |
|
101 return (-1); |
|
102 } |
|
103 |
|
104 efb_save_palet(); |
|
105 efb_set_palet(); |
|
106 |
|
107 /* |
|
108 * Allow a SIGHUP, SIGINT, SIGALRM, or SIGTERM to interrupt our |
|
109 * memory_test. These signals should already be masked from a |
|
110 * call to efb_block_signals. |
|
111 */ |
|
112 |
|
113 /* Save the current signals. */ |
|
114 |
|
115 sigaction(SIGHUP, NULL, &oldhup); |
|
116 sigaction(SIGINT, NULL, &oldint); |
|
117 sigaction(SIGALRM, NULL, &oldalrm); |
|
118 sigaction(SIGTERM, NULL, &oldterm); |
|
119 |
|
120 /* Setup up new signal action. */ |
|
121 |
|
122 newsigact.sa_handler = efb_signal_routine; |
|
123 sigemptyset(&newsigact.sa_mask); |
|
124 newsigact.sa_flags = 0; |
|
125 |
|
126 signo = sigsetjmp(efb_xw.xw_sigjmpbuf, 1); |
|
127 if (!signo) { |
|
128 /* First time goes here. */ |
|
129 |
|
130 /* Set signal routines. */ |
|
131 |
|
132 if (oldhup.sa_handler != SIG_IGN) |
|
133 sigaction(SIGHUP, &newsigact, NULL); |
|
134 if (oldint.sa_handler != SIG_IGN) |
|
135 sigaction(SIGINT, &newsigact, NULL); |
|
136 if (oldalrm.sa_handler != SIG_IGN) |
|
137 sigaction(SIGALRM, &newsigact, NULL); |
|
138 if (oldterm.sa_handler != SIG_IGN) |
|
139 sigaction(SIGTERM, &newsigact, NULL); |
|
140 |
|
141 for (i = 0; access_mode[i] != 0; i++) { |
|
142 /* Unmask SIGHUP, SIGINT, SIGALRM, SIGTERM. */ |
|
143 |
|
144 sigprocmask(SIG_SETMASK, &efb_xw.xw_procmask, |
|
145 &oldprocmask); |
|
146 |
|
147 check_plane(efb_info.efb_pixelsize * 8, |
|
148 access_mode[i], |
|
149 efb_info.efb_linesize / efb_info.efb_pixelsize, |
|
150 efb_info.efb_height, |
|
151 efb_info.efb_width, |
|
152 efb_info.efb_pixelsize, |
|
153 (caddr_t)efb_info.efb_fb_ptr); |
|
154 |
|
155 /* Mask SIGHUP, SIGINT, SIGALRM, SIGTERM. */ |
|
156 |
|
157 sigprocmask(SIG_SETMASK, &oldprocmask, NULL); |
|
158 |
|
159 signo = efb_check_for_interrupt(); |
|
160 if (signo != 0) |
|
161 break; |
|
162 } |
|
163 |
|
164 /* Restore the signals. */ |
|
165 |
|
166 if (oldhup.sa_handler != SIG_IGN) |
|
167 sigaction(SIGHUP, &oldhup, NULL); |
|
168 if (oldint.sa_handler != SIG_IGN) |
|
169 sigaction(SIGINT, &oldint, NULL); |
|
170 if (oldalrm.sa_handler != SIG_IGN) |
|
171 sigaction(SIGALRM, &oldalrm, NULL); |
|
172 if (oldterm.sa_handler != SIG_IGN) |
|
173 sigaction(SIGTERM, &oldterm, NULL); |
|
174 } |
|
175 |
|
176 else { |
|
177 /* We come here from the siglongjmp in efb_signal_routine. */ |
|
178 |
|
179 /* Mask SIGHUP, SIGINT, SIGALRM, SIGTERM. */ |
|
180 |
|
181 sigprocmask(SIG_SETMASK, &oldprocmask, NULL); |
|
182 |
|
183 /* Restore the signals. */ |
|
184 |
|
185 if (oldhup.sa_handler != SIG_IGN) |
|
186 sigaction(SIGHUP, &oldhup, NULL); |
|
187 if (oldint.sa_handler != SIG_IGN) |
|
188 sigaction(SIGINT, &oldint, NULL); |
|
189 if (oldalrm.sa_handler != SIG_IGN) |
|
190 sigaction(SIGALRM, &oldalrm, NULL); |
|
191 if (oldterm.sa_handler != SIG_IGN) |
|
192 sigaction(SIGTERM, &oldterm, NULL); |
|
193 |
|
194 /* Cause us to get the signal, when we unmask the signals. */ |
|
195 |
|
196 kill(getpid(), signo); |
|
197 } |
|
198 |
|
199 efb_restore_palet(); |
|
200 |
|
201 if (efb_unmap_mem(rp, GRAPHICS_ERR_MEMORY_MSG) != 0) |
|
202 return (-1); |
|
203 |
|
204 return (0); |
|
205 } |
|
206 |
57 |
207 |
58 void |
208 void |
59 Write8(void *addr, uint8_t data) { |
209 check_plane( |
60 *(uint8_t *)addr = data; |
210 register int const num_planes, |
|
211 register int const access_mode, |
|
212 register int const fb_pitch, |
|
213 register int const fb_height, |
|
214 register int const fb_width, |
|
215 register int const bytepp, |
|
216 register caddr_t const base) |
|
217 { |
|
218 register int x; |
|
219 register int y; |
|
220 register int complement; |
|
221 |
|
222 /* Set up raster for this plane group */ |
|
223 |
|
224 init_data(num_planes); |
|
225 |
|
226 /* Cover each 64x64 chunk of screen space */ |
|
227 |
|
228 y = 0; |
|
229 while (y < fb_height) { |
|
230 x = 0; |
|
231 while (x < fb_width) { |
|
232 if (x + 63 > fb_width) |
|
233 x = fb_width - 64; |
|
234 if (y + 63 > fb_height) |
|
235 y = fb_height - 64; |
|
236 |
|
237 /* Do each chunk twice - once normal, once complement */ |
|
238 |
|
239 for (complement = B_FALSE; |
|
240 complement <= B_TRUE; |
|
241 complement++) { |
|
242 write_read(x, y, |
|
243 (boolean_t)complement, |
|
244 access_mode, |
|
245 B_TRUE, |
|
246 fb_pitch, |
|
247 bytepp, |
|
248 base) || |
|
249 write_read(x, y, |
|
250 (boolean_t)complement, |
|
251 access_mode, |
|
252 B_FALSE, |
|
253 fb_pitch, |
|
254 bytepp, |
|
255 base); |
|
256 } |
|
257 |
|
258 /* Move over one 64x64 chunk */ |
|
259 |
|
260 x += 64; |
|
261 } |
|
262 |
|
263 /* Move down one 64x64 chunk */ |
|
264 |
|
265 y += 64; |
|
266 } |
61 } |
267 } |
62 |
268 |
|
269 |
63 void |
270 void |
64 Write16(void *addr, uint16_t data) { |
271 init_data( |
65 *(uint16_t *)addr = data; |
272 register int const num_planes) |
|
273 { |
|
274 register int i; |
|
275 register int j; |
|
276 |
|
277 /* Get memory to store data */ |
|
278 |
|
279 /* Write data to memory */ |
|
280 |
|
281 for (i = 0; i < num_planes * 8; i++) { |
|
282 for (j = 0; j < 8; j++) { |
|
283 |
|
284 /* Figure out the value to write */ |
|
285 |
|
286 data[i].val[j] = ((unsigned long long) |
|
287 test_data() << 32) | test_data(); |
|
288 cdata[i].val[j] = ~data[i].val[j]; |
|
289 } |
|
290 } |
66 } |
291 } |
67 |
292 |
68 void |
293 |
69 Write32(void *addr, uint32_t data) { |
294 |
70 *(uint32_t *)addr = data; |
295 uint_t |
71 } |
296 test_data( |
72 |
297 void) |
73 void |
298 { |
74 Write64(void *addr, uint64_t data) { |
299 register uint_t ret; |
75 *(uint64_t *)addr = data; |
300 |
76 } |
301 ret = (uint_t)mrand48(); |
77 |
|
78 uint8_t |
|
79 read8(void *addr) { |
|
80 return (*(uint8_t *)addr); |
|
81 } |
|
82 |
|
83 uint16_t |
|
84 read16(void *addr) { |
|
85 return (*(uint16_t *)addr); |
|
86 } |
|
87 |
|
88 uint32_t |
|
89 read32(void *addr) { |
|
90 return (*(uint32_t *)addr); |
|
91 } |
|
92 |
|
93 uint64_t |
|
94 read64(void *addr) { |
|
95 return (*(uint64_t *)addr); |
|
96 } |
|
97 |
|
98 |
|
99 u_int |
|
100 test_data() { |
|
101 u_int ret; |
|
102 |
|
103 ret = (u_int)mrand48(); |
|
104 return (ret); |
302 return (ret); |
105 } |
303 } |
106 |
304 |
107 MemType *data; |
|
108 MemType *cdata; |
|
109 |
|
110 |
|
111 void |
|
112 plane_change(int num_planes_, caddr_t base_, int sh, int sw) |
|
113 { |
|
114 int num_planes = num_planes_; |
|
115 caddr_t base = base_; |
|
116 int i; |
|
117 int j; |
|
118 |
|
119 int pix_per_write, old_pix_per_write; |
|
120 |
|
121 /* Get memory to store data */ |
|
122 |
|
123 int memcount = num_planes * 8; |
|
124 |
|
125 if (data) free(data); |
|
126 if (cdata) free(cdata); |
|
127 |
|
128 data = (MemType *)memalign(64, memcount * sizeof (MemType)); |
|
129 cdata = (MemType *)memalign(64, memcount * sizeof (MemType)); |
|
130 |
|
131 /* Write data to memory */ |
|
132 for (i = 0; i < memcount; i++) { |
|
133 for (j = 0; j < 8; j++) { |
|
134 /* Figure out the value to write */ |
|
135 data[i].val[j] = ((unsigned long long)test_data() << 32) |
|
136 | test_data(); |
|
137 cdata[i].val[j] = ~data[i].val[j]; |
|
138 } |
|
139 } |
|
140 |
|
141 } /* plane_change() */ |
|
142 |
|
143 |
305 |
144 boolean_t |
306 boolean_t |
145 write_read(int xoff, int yoff, boolean_t complement, int access_mode, |
307 write_read( |
146 boolean_t pass, int fb_pitch, int bytepp, caddr_t base) |
308 register int const xoff, |
147 { |
309 register int const yoff, |
148 MemType *dp; |
310 register boolean_t const complement, |
149 int pitch = fb_pitch; |
311 register int const access_mode, |
150 int x; |
312 register boolean_t const pass, |
151 int y; |
313 register int const fb_pitch, |
152 int i; |
314 register int const bytepp, |
153 caddr_t mem_addr; |
315 register caddr_t const base) |
154 caddr_t dp_addr; |
316 { |
155 u_int second_rdval; |
317 register MemType *const dp = complement ? cdata : data; |
156 MemType *rdval; |
318 register int const pitch = fb_pitch; |
157 int subscr = 0; |
319 register int x; |
158 |
320 register int y; |
159 if (complement) { |
321 register int i; |
160 dp = cdata; |
322 register caddr_t mem_addr; |
161 } else { |
323 register int subscr = 0; |
162 dp = data; |
|
163 } |
|
164 |
324 |
165 /* Write Data to Screen */ |
325 /* Write Data to Screen */ |
|
326 |
166 for (y = yoff; y < yoff + 64; y++) { |
327 for (y = yoff; y < yoff + 64; y++) { |
167 for (x = xoff * bytepp, i = 0; |
328 for (x = xoff * bytepp, i = 0; |
168 x < ((xoff + 64) *bytepp); |
329 x < ((xoff + 64) * bytepp); |
169 x += access_mode, i++) { |
330 x += access_mode, i++) { |
170 mem_addr = (y*pitch*bytepp) + x + base; |
331 mem_addr = (y * pitch * bytepp) + x + base; |
171 /* Check which access mode to use for write */ |
332 |
172 switch (access_mode) { |
333 /* Check which access mode to use for write */ |
173 case 8: /* long long (8-byte) access mode */ |
334 |
174 Write64(mem_addr, dp[subscr].val[i]); |
335 switch (access_mode) { |
175 break; |
336 case 8: /* long long (8-byte) access mode */ |
176 case 4: /* word (4-byte) access mode */ |
337 *(uint64_t volatile *)mem_addr = |
177 Write32(mem_addr, dp[subscr].word[i]); |
338 dp[subscr].val[i]; |
178 break; |
339 break; |
179 case 2: /* short (2-byte) access mode */ |
340 |
180 Write16(mem_addr, dp[subscr].halfwd[i]); |
341 case 4: /* word (4-byte) access mode */ |
181 break; |
342 *(uint32_t volatile *)mem_addr = |
182 default: /* default to byte access */ |
343 dp[subscr].word[i]; |
183 Write8(mem_addr, dp[subscr].byte[i]); |
344 break; |
184 break; |
345 |
185 } |
346 case 2: /* short (2-byte) access mode */ |
186 } |
347 *(uint16_t volatile *)mem_addr = |
187 subscr++; |
348 dp[subscr].halfwd[i]; |
|
349 break; |
|
350 |
|
351 default: /* default to byte access */ |
|
352 *(uint8_t volatile *)mem_addr = |
|
353 dp[subscr].byte[i]; |
|
354 break; |
|
355 } |
|
356 } |
|
357 subscr++; |
188 } |
358 } |
189 |
359 |
190 /* Read the Data From the Screen */ |
360 /* Read the Data From the Screen */ |
191 |
361 |
192 rdval = (MemType *)memalign(64, (sizeof (MemType) * bytepp)); |
|
193 |
|
194 for (y = yoff; y < yoff + 64; y++) { |
362 for (y = yoff; y < yoff + 64; y++) { |
195 for (x = xoff * bytepp, i = 0; |
363 for (x = xoff * bytepp, i = 0; |
196 x < ((xoff + 64) * bytepp); |
364 x < ((xoff + 64) * bytepp); |
197 x += access_mode, i++) { |
365 x += access_mode, i++) { |
198 mem_addr = (y*pitch*bytepp) + x + base; |
366 mem_addr = (y * pitch * bytepp) + x + base; |
199 |
367 |
200 switch (access_mode) { |
368 switch (access_mode) { |
201 case 8: /* long long (8-byte) access mode */ |
369 case 8: /* long long (8-byte) access mode */ |
202 rdval->val[i] = read64(mem_addr); |
370 rdval[0].val[i] = |
203 break; |
371 *(uint64_t volatile const *)mem_addr; |
204 case 4: /* word (4-byte) access mode */ |
372 break; |
205 rdval->word[i] = read32(mem_addr); |
373 |
206 break; |
374 case 4: /* word (4-byte) access mode */ |
207 case 2: /* short (2-byte) access mode */ |
375 rdval[0].word[i] = |
208 rdval->halfwd[i] = read16(mem_addr); |
376 *(uint32_t volatile const *)mem_addr; |
209 break; |
377 break; |
210 default: /* default to byte access */ |
378 |
211 rdval->byte[i] = read8(mem_addr); |
379 case 2: /* short (2-byte) access mode */ |
212 break; |
380 rdval[0].halfwd[i] = |
213 } |
381 *(uint16_t volatile const *)mem_addr; |
214 } |
382 break; |
|
383 |
|
384 default: /* default to byte access */ |
|
385 rdval[0].byte[i] = |
|
386 *(uint8_t volatile const *)mem_addr; |
|
387 break; |
|
388 } |
|
389 } |
215 |
390 |
216 /* TODO: verification */ |
391 /* TODO: verification */ |
217 if (memcmp(rdval, dp[subscr].byte, 64 * bytepp) != 0) { |
392 |
218 switch (access_mode) { |
393 if (memcmp(rdval, dp[subscr].byte, 64 * bytepp) != 0) { |
219 case 8: /* long long (8-byte) access mode */ |
394 switch (access_mode) { |
220 for (i = 0; i < (16 * bytepp); i++) { |
395 case 8: /* long long (8-byte) access mode */ |
221 if (rdval->word[i] != dp[subscr].word[i]) { |
396 for (i = 0; i < (8 * bytepp); i++) { |
222 free(rdval); |
397 if (rdval[0].val[i] != |
223 return (B_FALSE); |
398 dp[subscr].val[i]) |
224 } |
399 return (B_FALSE); |
|
400 } |
|
401 break; |
|
402 |
|
403 case 4: /* word (4-byte) access mode */ |
|
404 for (i = 0; i < (16 * bytepp); i++) { |
|
405 if (rdval[0].word[i] != |
|
406 dp[subscr].word[i]) |
|
407 return (B_FALSE); |
|
408 } |
|
409 break; |
|
410 |
|
411 case 2: /* short (2-byte) access mode */ |
|
412 for (i = 0; i < (32 * bytepp); i++) { |
|
413 if (rdval[0].halfwd[i] != |
|
414 dp[subscr].halfwd[i]) |
|
415 return (B_FALSE); |
|
416 } |
|
417 break; |
|
418 |
|
419 default: /* default to byte access */ |
|
420 for (i = 0; i < (64 * bytepp); i++) { |
|
421 if (rdval[0].byte[i] != |
|
422 dp[subscr].byte[i]) |
|
423 return (B_FALSE); |
|
424 } |
|
425 break; |
225 } |
426 } |
226 break; |
427 } |
227 case 4: /* word (4-byte) access mode */ |
428 subscr++; |
228 for (i = 0; i < (16 * bytepp); i++) { |
|
229 if (rdval->word[i] != dp[subscr].word[i]) { |
|
230 free(rdval); |
|
231 return (B_FALSE); |
|
232 } |
|
233 } |
|
234 break; |
|
235 case 2: /* short (2-byte) access mode */ |
|
236 for (i = 0; i < (32 * bytepp); i++) { |
|
237 if (rdval->halfwd[i] != dp[subscr].halfwd[i]) { |
|
238 free(rdval); |
|
239 return (B_FALSE); |
|
240 } |
|
241 } |
|
242 break; |
|
243 default: /* default to byte access */ |
|
244 for (i = 0; i < (64 * bytepp); i++) { |
|
245 if (rdval->byte[i] != dp[subscr].byte[i]) { |
|
246 free(rdval); |
|
247 return (B_FALSE); |
|
248 } |
|
249 } |
|
250 break; |
|
251 } |
|
252 } |
|
253 subscr ++; |
|
254 } |
429 } |
255 |
430 |
256 return (B_TRUE); |
431 return (B_TRUE); |
257 |
432 } |
258 } /* write_read() */ |
|
259 |
|
260 |
|
261 void |
|
262 check_plane(int num_planes, int access_mode, char *test_name, |
|
263 int fb_offset, int fb_pitch, int fb_height, |
|
264 int fb_width, int bytepp, caddr_t base) |
|
265 { |
|
266 int x; |
|
267 int y; |
|
268 int complement; |
|
269 |
|
270 /* Set up refber for this plane group */ |
|
271 plane_change(num_planes, base + fb_offset, fb_width, fb_height); |
|
272 |
|
273 /* Cover each 64x64 chunk of screen space */ |
|
274 y = 0; |
|
275 while (y < fb_height) { |
|
276 x = 0; |
|
277 while (x < fb_width) { |
|
278 if (x + 63 > fb_width) x = fb_width - 64; |
|
279 if (y + 63 > fb_height) y = fb_height - 64; |
|
280 |
|
281 /* Do each chunk twice - once normal, once complement */ |
|
282 for (complement = B_FALSE; |
|
283 complement <= B_TRUE; |
|
284 complement++) { |
|
285 write_read(x, y, |
|
286 (boolean_t)complement, |
|
287 access_mode, |
|
288 B_TRUE, |
|
289 fb_pitch, |
|
290 bytepp, |
|
291 base) || |
|
292 write_read(x, y, |
|
293 (boolean_t)complement, |
|
294 access_mode, |
|
295 B_FALSE, |
|
296 fb_pitch, |
|
297 bytepp, |
|
298 base); |
|
299 } |
|
300 |
|
301 /* Move over one 64x64 chunk */ |
|
302 x += 64; |
|
303 } |
|
304 |
|
305 /* Move down one 64x64 chunk */ |
|
306 y += 64; |
|
307 } |
|
308 |
|
309 } /* check_plane() */ |
|
310 |
|
311 |
|
312 void |
|
313 memory_test(return_packet *rp, int fd) |
|
314 { |
|
315 struct efb_info efb_info; |
|
316 struct efb_info *pEFB; |
|
317 unsigned int red; |
|
318 unsigned char *fbaddr; |
|
319 int i; |
|
320 int bytepp; |
|
321 int fb_offset, fb_pitch, fb_height, fb_width; |
|
322 |
|
323 pEFB = &efb_info; |
|
324 pEFB->fd = fd; |
|
325 |
|
326 /* |
|
327 * map the registers & frame buffers memory |
|
328 */ |
|
329 if (efb_map_mem(pEFB, rp, GRAPHICS_ERR_MEMORY_MSG) == -1) { |
|
330 return; |
|
331 } |
|
332 |
|
333 if (efb_init_info(pEFB) == -1) { |
|
334 return; |
|
335 } |
|
336 |
|
337 for (i = 0; access_mode[i] != 0; i++) { |
|
338 check_plane((size_t) pEFB->bitsPerPixel, access_mode[i], |
|
339 (char *)"Memory Test", |
|
340 0, pEFB->screenWidth, pEFB->screenHeight, pEFB->screenWidth, |
|
341 pEFB->bitsPerPixel/8, (caddr_t)pEFB->FBvaddr); |
|
342 } |
|
343 |
|
344 /* |
|
345 * Unmap the registers & frame buffers memory |
|
346 */ |
|
347 if (efb_unmap_mem(pEFB, rp, GRAPHICS_ERR_MEMORY_MSG) == -1) { |
|
348 return; |
|
349 } |
|
350 } /* memory_test() */ |
|
351 |
433 |
352 |
434 |
353 /* End of memory.c */ |
435 /* End of memory.c */ |