1117N/A/*
1368N/A * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
1117N/A *
1117N/A * Permission is hereby granted, free of charge, to any person obtaining a
1117N/A * copy of this software and associated documentation files (the "Software"),
1117N/A * to deal in the Software without restriction, including without limitation
1117N/A * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1117N/A * and/or sell copies of the Software, and to permit persons to whom the
1117N/A * Software is furnished to do so, subject to the following conditions:
1117N/A *
1117N/A * The above copyright notice and this permission notice (including the next
1117N/A * paragraph) shall be included in all copies or substantial portions of the
1117N/A * Software.
1117N/A *
1117N/A * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1117N/A * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1117N/A * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1117N/A * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1117N/A * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1117N/A * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
1117N/A * DEALINGS IN THE SOFTWARE.
1117N/A */
1117N/A
1368N/A#include "libvtsSUNWefb.h" /* Common VTS library definitions */
1117N/A
1117N/Atypedef union MemType {
1117N/A uint64_t val[8];
1117N/A uint32_t word[16];
1117N/A uint16_t halfwd[32];
1117N/A uint8_t byte[64];
1117N/A} MemType;
1117N/A
1117N/Astatic const int access_mode[] = {
1117N/A 1, 2, 4, 8, 0
1117N/A};
1117N/A
1368N/Astatic MemType data[32 * 8];
1368N/Astatic MemType cdata[32 * 8];
1368N/Astatic MemType rdval[4];
1117N/A
1368N/A/*
1368N/A * efb_test_memory()
1368N/A *
1368N/A * This test will open the device and read and write to all memory
1368N/A * addresses.
1368N/A */
1117N/A
1368N/Areturn_packet *
1368N/Aefb_test_memory(
1368N/A register int const fd)
1368N/A{
1368N/A static return_packet rp;
1117N/A
1368N/A memset(&rp, 0, sizeof (return_packet));
1117N/A
1368N/A if (gfx_vts_debug_mask & GRAPHICS_VTS_MEM_OFF)
1368N/A return (&rp);
1117N/A
1368N/A TraceMessage(VTS_DEBUG, "efb_test_memory",
1368N/A "efb_test_memory running\n");
1368N/A
1368N/A efb_block_signals();
1368N/A
1368N/A efb_lock_display();
1117N/A
1368N/A memory_test(&rp, fd);
1368N/A
1368N/A efb_unlock_display();
1368N/A
1368N/A efb_restore_signals();
1117N/A
1368N/A TraceMessage(VTS_DEBUG, "efb_test_memory",
1368N/A "efb_test_memory completed\n");
1117N/A
1368N/A return (&rp);
1368N/A} /* efb_test_memory() */
1117N/A
1117N/A
1368N/Aint
1368N/Amemory_test(
1368N/A register return_packet *const rp,
1368N/A register int const fd)
1368N/A{
1368N/A register size_t i;
1368N/A register int signo;
1368N/A struct sigaction oldhup;
1368N/A struct sigaction oldint;
1368N/A struct sigaction oldalrm;
1368N/A struct sigaction oldterm;
1368N/A struct sigaction newsigact;
1368N/A sigset_t oldprocmask;
1368N/A
1368N/A memset(&efb_info, 0, sizeof (efb_info));
1368N/A efb_info.efb_fd = fd;
1368N/A
1368N/A if (efb_map_mem(rp, GRAPHICS_ERR_MEMORY_MSG) != 0)
1368N/A return (-1);
1368N/A
1368N/A if (efb_init_info(rp, GRAPHICS_ERR_MEMORY_MSG) != 0) {
1368N/A efb_unmap_mem(NULL, GRAPHICS_ERR_MEMORY_MSG);
1368N/A return (-1);
1368N/A }
1368N/A
1368N/A efb_save_palet();
1368N/A efb_set_palet();
1368N/A
1368N/A /*
1368N/A * Allow a SIGHUP, SIGINT, SIGALRM, or SIGTERM to interrupt our
1368N/A * memory_test. These signals should already be masked from a
1368N/A * call to efb_block_signals.
1368N/A */
1368N/A
1368N/A /* Save the current signals. */
1368N/A
1368N/A sigaction(SIGHUP, NULL, &oldhup);
1368N/A sigaction(SIGINT, NULL, &oldint);
1368N/A sigaction(SIGALRM, NULL, &oldalrm);
1368N/A sigaction(SIGTERM, NULL, &oldterm);
1368N/A
1368N/A /* Setup up new signal action. */
1368N/A
1368N/A newsigact.sa_handler = efb_signal_routine;
1368N/A sigemptyset(&newsigact.sa_mask);
1368N/A newsigact.sa_flags = 0;
1368N/A
1368N/A signo = sigsetjmp(efb_xw.xw_sigjmpbuf, 1);
1368N/A if (!signo) {
1368N/A /* First time goes here. */
1368N/A
1368N/A /* Set signal routines. */
1368N/A
1368N/A if (oldhup.sa_handler != SIG_IGN)
1368N/A sigaction(SIGHUP, &newsigact, NULL);
1368N/A if (oldint.sa_handler != SIG_IGN)
1368N/A sigaction(SIGINT, &newsigact, NULL);
1368N/A if (oldalrm.sa_handler != SIG_IGN)
1368N/A sigaction(SIGALRM, &newsigact, NULL);
1368N/A if (oldterm.sa_handler != SIG_IGN)
1368N/A sigaction(SIGTERM, &newsigact, NULL);
1117N/A
1368N/A for (i = 0; access_mode[i] != 0; i++) {
1368N/A /* Unmask SIGHUP, SIGINT, SIGALRM, SIGTERM. */
1368N/A
1368N/A sigprocmask(SIG_SETMASK, &efb_xw.xw_procmask,
1368N/A &oldprocmask);
1368N/A
1368N/A check_plane(efb_info.efb_pixelsize * 8,
1368N/A access_mode[i],
1368N/A efb_info.efb_linesize / efb_info.efb_pixelsize,
1368N/A efb_info.efb_height,
1368N/A efb_info.efb_width,
1368N/A efb_info.efb_pixelsize,
1368N/A (caddr_t)efb_info.efb_fb_ptr);
1368N/A
1368N/A /* Mask SIGHUP, SIGINT, SIGALRM, SIGTERM. */
1368N/A
1368N/A sigprocmask(SIG_SETMASK, &oldprocmask, NULL);
1368N/A
1368N/A signo = efb_check_for_interrupt();
1368N/A if (signo != 0)
1368N/A break;
1368N/A }
1368N/A
1368N/A /* Restore the signals. */
1368N/A
1368N/A if (oldhup.sa_handler != SIG_IGN)
1368N/A sigaction(SIGHUP, &oldhup, NULL);
1368N/A if (oldint.sa_handler != SIG_IGN)
1368N/A sigaction(SIGINT, &oldint, NULL);
1368N/A if (oldalrm.sa_handler != SIG_IGN)
1368N/A sigaction(SIGALRM, &oldalrm, NULL);
1368N/A if (oldterm.sa_handler != SIG_IGN)
1368N/A sigaction(SIGTERM, &oldterm, NULL);
1368N/A }
1368N/A
1368N/A else {
1368N/A /* We come here from the siglongjmp in efb_signal_routine. */
1368N/A
1368N/A /* Mask SIGHUP, SIGINT, SIGALRM, SIGTERM. */
1368N/A
1368N/A sigprocmask(SIG_SETMASK, &oldprocmask, NULL);
1368N/A
1368N/A /* Restore the signals. */
1368N/A
1368N/A if (oldhup.sa_handler != SIG_IGN)
1368N/A sigaction(SIGHUP, &oldhup, NULL);
1368N/A if (oldint.sa_handler != SIG_IGN)
1368N/A sigaction(SIGINT, &oldint, NULL);
1368N/A if (oldalrm.sa_handler != SIG_IGN)
1368N/A sigaction(SIGALRM, &oldalrm, NULL);
1368N/A if (oldterm.sa_handler != SIG_IGN)
1368N/A sigaction(SIGTERM, &oldterm, NULL);
1368N/A
1368N/A /* Cause us to get the signal, when we unmask the signals. */
1368N/A
1368N/A kill(getpid(), signo);
1368N/A }
1368N/A
1368N/A efb_restore_palet();
1368N/A
1368N/A if (efb_unmap_mem(rp, GRAPHICS_ERR_MEMORY_MSG) != 0)
1368N/A return (-1);
1368N/A
1368N/A return (0);
1117N/A}
1117N/A
1117N/A
1117N/Avoid
1368N/Acheck_plane(
1368N/A register int const num_planes,
1368N/A register int const access_mode,
1368N/A register int const fb_pitch,
1368N/A register int const fb_height,
1368N/A register int const fb_width,
1368N/A register int const bytepp,
1368N/A register caddr_t const base)
1117N/A{
1368N/A register int x;
1368N/A register int y;
1368N/A register int complement;
1368N/A
1368N/A /* Set up raster for this plane group */
1368N/A
1368N/A init_data(num_planes);
1368N/A
1368N/A /* Cover each 64x64 chunk of screen space */
1368N/A
1368N/A y = 0;
1368N/A while (y < fb_height) {
1368N/A x = 0;
1368N/A while (x < fb_width) {
1368N/A if (x + 63 > fb_width)
1368N/A x = fb_width - 64;
1368N/A if (y + 63 > fb_height)
1368N/A y = fb_height - 64;
1368N/A
1368N/A /* Do each chunk twice - once normal, once complement */
1117N/A
1368N/A for (complement = B_FALSE;
1368N/A complement <= B_TRUE;
1368N/A complement++) {
1368N/A write_read(x, y,
1368N/A (boolean_t)complement,
1368N/A access_mode,
1368N/A B_TRUE,
1368N/A fb_pitch,
1368N/A bytepp,
1368N/A base) ||
1368N/A write_read(x, y,
1368N/A (boolean_t)complement,
1368N/A access_mode,
1368N/A B_FALSE,
1368N/A fb_pitch,
1368N/A bytepp,
1368N/A base);
1368N/A }
1368N/A
1368N/A /* Move over one 64x64 chunk */
1368N/A
1368N/A x += 64;
1368N/A }
1368N/A
1368N/A /* Move down one 64x64 chunk */
1368N/A
1368N/A y += 64;
1368N/A }
1368N/A}
1368N/A
1368N/A
1368N/Avoid
1368N/Ainit_data(
1368N/A register int const num_planes)
1368N/A{
1368N/A register int i;
1368N/A register int j;
1117N/A
1117N/A /* Get memory to store data */
1117N/A
1368N/A /* Write data to memory */
1117N/A
1368N/A for (i = 0; i < num_planes * 8; i++) {
1368N/A for (j = 0; j < 8; j++) {
1117N/A
1368N/A /* Figure out the value to write */
1117N/A
1368N/A data[i].val[j] = ((unsigned long long)
1368N/A test_data() << 32) | test_data();
1368N/A cdata[i].val[j] = ~data[i].val[j];
1368N/A }
1117N/A }
1368N/A}
1117N/A
1368N/A
1368N/A
1368N/Auint_t
1368N/Atest_data(
1368N/A void)
1368N/A{
1368N/A register uint_t ret;
1368N/A
1368N/A ret = (uint_t)mrand48();
1368N/A return (ret);
1368N/A}
1117N/A
1117N/A
1117N/Aboolean_t
1368N/Awrite_read(
1368N/A register int const xoff,
1368N/A register int const yoff,
1368N/A register boolean_t const complement,
1368N/A register int const access_mode,
1368N/A register boolean_t const pass,
1368N/A register int const fb_pitch,
1368N/A register int const bytepp,
1368N/A register caddr_t const base)
1117N/A{
1368N/A register MemType *const dp = complement ? cdata : data;
1368N/A register int const pitch = fb_pitch;
1368N/A register int x;
1368N/A register int y;
1368N/A register int i;
1368N/A register caddr_t mem_addr;
1368N/A register int subscr = 0;
1117N/A
1117N/A /* Write Data to Screen */
1368N/A
1117N/A for (y = yoff; y < yoff + 64; y++) {
1368N/A for (x = xoff * bytepp, i = 0;
1368N/A x < ((xoff + 64) * bytepp);
1368N/A x += access_mode, i++) {
1368N/A mem_addr = (y * pitch * bytepp) + x + base;
1368N/A
1368N/A /* Check which access mode to use for write */
1368N/A
1368N/A switch (access_mode) {
1368N/A case 8: /* long long (8-byte) access mode */
1368N/A *(uint64_t volatile *)mem_addr =
1368N/A dp[subscr].val[i];
1368N/A break;
1368N/A
1368N/A case 4: /* word (4-byte) access mode */
1368N/A *(uint32_t volatile *)mem_addr =
1368N/A dp[subscr].word[i];
1368N/A break;
1368N/A
1368N/A case 2: /* short (2-byte) access mode */
1368N/A *(uint16_t volatile *)mem_addr =
1368N/A dp[subscr].halfwd[i];
1368N/A break;
1368N/A
1368N/A default: /* default to byte access */
1368N/A *(uint8_t volatile *)mem_addr =
1368N/A dp[subscr].byte[i];
1368N/A break;
1368N/A }
1117N/A }
1368N/A subscr++;
1117N/A }
1117N/A
1117N/A /* Read the Data From the Screen */
1117N/A
1368N/A for (y = yoff; y < yoff + 64; y++) {
1368N/A for (x = xoff * bytepp, i = 0;
1368N/A x < ((xoff + 64) * bytepp);
1368N/A x += access_mode, i++) {
1368N/A mem_addr = (y * pitch * bytepp) + x + base;
1117N/A
1368N/A switch (access_mode) {
1368N/A case 8: /* long long (8-byte) access mode */
1368N/A rdval[0].val[i] =
1368N/A *(uint64_t volatile const *)mem_addr;
1368N/A break;
1117N/A
1368N/A case 4: /* word (4-byte) access mode */
1368N/A rdval[0].word[i] =
1368N/A *(uint32_t volatile const *)mem_addr;
1368N/A break;
1368N/A
1368N/A case 2: /* short (2-byte) access mode */
1368N/A rdval[0].halfwd[i] =
1368N/A *(uint16_t volatile const *)mem_addr;
1368N/A break;
1368N/A
1368N/A default: /* default to byte access */
1368N/A rdval[0].byte[i] =
1368N/A *(uint8_t volatile const *)mem_addr;
1368N/A break;
1368N/A }
1117N/A }
1117N/A
1117N/A /* TODO: verification */
1368N/A
1368N/A if (memcmp(rdval, dp[subscr].byte, 64 * bytepp) != 0) {
1368N/A switch (access_mode) {
1368N/A case 8: /* long long (8-byte) access mode */
1368N/A for (i = 0; i < (8 * bytepp); i++) {
1368N/A if (rdval[0].val[i] !=
1368N/A dp[subscr].val[i])
1368N/A return (B_FALSE);
1368N/A }
1368N/A break;
1368N/A
1368N/A case 4: /* word (4-byte) access mode */
1368N/A for (i = 0; i < (16 * bytepp); i++) {
1368N/A if (rdval[0].word[i] !=
1368N/A dp[subscr].word[i])
1368N/A return (B_FALSE);
1368N/A }
1368N/A break;
1368N/A
1368N/A case 2: /* short (2-byte) access mode */
1368N/A for (i = 0; i < (32 * bytepp); i++) {
1368N/A if (rdval[0].halfwd[i] !=
1368N/A dp[subscr].halfwd[i])
1368N/A return (B_FALSE);
1368N/A }
1368N/A break;
1368N/A
1368N/A default: /* default to byte access */
1368N/A for (i = 0; i < (64 * bytepp); i++) {
1368N/A if (rdval[0].byte[i] !=
1368N/A dp[subscr].byte[i])
1368N/A return (B_FALSE);
1368N/A }
1368N/A break;
1117N/A }
1117N/A }
1368N/A subscr++;
1117N/A }
1117N/A
1117N/A return (B_TRUE);
1368N/A}
1117N/A
1117N/A
1117N/A/* End of memory.c */