1117N/A/*
1407N/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
1407N/A#include "libvtsSUNWast.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};
1407N/A
1407N/Astatic MemType data[32 * 8];
1407N/Astatic MemType cdata[32 * 8];
1407N/Astatic MemType rdval[4];
1117N/A
1407N/A/*
1407N/A * ast_test_memory()
1407N/A *
1407N/A * This test will open the device and read and write to all memory
1407N/A * addresses.
1407N/A */
1117N/A
1407N/Areturn_packet *
1407N/Aast_test_memory(
1407N/A register int const fd)
1407N/A{
1407N/A static return_packet rp;
1117N/A
1407N/A memset(&rp, 0, sizeof (return_packet));
1117N/A
1407N/A if (gfx_vts_debug_mask & GRAPHICS_VTS_MEM_OFF)
1407N/A return (&rp);
1117N/A
1407N/A TraceMessage(VTS_DEBUG, "ast_test_memory",
1407N/A "ast_test_memory running\n");
1407N/A
1407N/A ast_block_signals();
1407N/A
1407N/A ast_lock_display();
1117N/A
1407N/A memory_test(&rp, fd);
1407N/A
1407N/A ast_unlock_display();
1407N/A
1407N/A ast_restore_signals();
1117N/A
1407N/A TraceMessage(VTS_DEBUG, "ast_test_memory",
1407N/A "ast_test_memory completed\n");
1117N/A
1407N/A return (&rp);
1407N/A} /* ast_test_memory() */
1117N/A
1117N/A
1407N/Aint
1407N/Amemory_test(
1407N/A register return_packet *const rp,
1407N/A register int const fd)
1407N/A{
1407N/A register size_t i;
1407N/A register int signo;
1407N/A struct sigaction oldhup;
1407N/A struct sigaction oldint;
1407N/A struct sigaction oldalrm;
1407N/A struct sigaction oldterm;
1407N/A struct sigaction newsigact;
1407N/A sigset_t oldprocmask;
1407N/A
1407N/A memset(&ast_info, 0, sizeof (ast_info));
1407N/A ast_info.ast_fd = fd;
1407N/A
1407N/A if (ast_map_mem(rp, GRAPHICS_ERR_MEMORY_MSG) != 0)
1407N/A return (-1);
1407N/A
1407N/A if (ast_init_info(rp, GRAPHICS_ERR_MEMORY_MSG) != 0) {
1407N/A ast_unmap_mem(NULL, GRAPHICS_ERR_MEMORY_MSG);
1407N/A return (-1);
1407N/A }
1407N/A
1407N/A ast_save_palet();
1407N/A ast_set_palet();
1407N/A
1407N/A /*
1407N/A * Allow a SIGHUP, SIGINT, SIGALRM, or SIGTERM to interrupt our
1407N/A * memory_test. These signals should already be masked from a
1407N/A * call to ast_block_signals.
1407N/A */
1407N/A
1407N/A /* Save the current signals. */
1407N/A
1407N/A sigaction(SIGHUP, NULL, &oldhup);
1407N/A sigaction(SIGINT, NULL, &oldint);
1407N/A sigaction(SIGALRM, NULL, &oldalrm);
1407N/A sigaction(SIGTERM, NULL, &oldterm);
1407N/A
1407N/A /* Setup up new signal action. */
1407N/A
1407N/A newsigact.sa_handler = ast_signal_routine;
1407N/A sigemptyset(&newsigact.sa_mask);
1407N/A newsigact.sa_flags = 0;
1407N/A
1407N/A signo = sigsetjmp(ast_xw.xw_sigjmpbuf, 1);
1407N/A if (!signo) {
1407N/A /* First time goes here. */
1407N/A
1407N/A /* Set signal routines. */
1407N/A
1407N/A if (oldhup.sa_handler != SIG_IGN)
1407N/A sigaction(SIGHUP, &newsigact, NULL);
1407N/A if (oldint.sa_handler != SIG_IGN)
1407N/A sigaction(SIGINT, &newsigact, NULL);
1407N/A if (oldalrm.sa_handler != SIG_IGN)
1407N/A sigaction(SIGALRM, &newsigact, NULL);
1407N/A if (oldterm.sa_handler != SIG_IGN)
1407N/A sigaction(SIGTERM, &newsigact, NULL);
1117N/A
1407N/A for (i = 0; access_mode[i] != 0; i++) {
1407N/A /* Unmask SIGHUP, SIGINT, SIGALRM, SIGTERM. */
1407N/A
1407N/A sigprocmask(SIG_SETMASK, &ast_xw.xw_procmask,
1407N/A &oldprocmask);
1407N/A
1407N/A check_plane(ast_info.ast_depth, access_mode[i],
1407N/A ast_info.ast_linesize / ast_info.ast_pixelsize,
1407N/A ast_info.ast_height,
1407N/A ast_info.ast_width, ast_info.ast_pixelsize,
1407N/A (caddr_t)ast_info.ast_fb_ptr);
1407N/A
1407N/A /* Mask SIGHUP, SIGINT, SIGALRM, SIGTERM. */
1407N/A
1407N/A sigprocmask(SIG_SETMASK, &oldprocmask, NULL);
1407N/A
1407N/A signo = ast_check_for_interrupt();
1407N/A if (signo != 0)
1407N/A break;
1407N/A }
1407N/A
1407N/A /* Restore the signals. */
1407N/A
1407N/A if (oldhup.sa_handler != SIG_IGN)
1407N/A sigaction(SIGHUP, &oldhup, NULL);
1407N/A if (oldint.sa_handler != SIG_IGN)
1407N/A sigaction(SIGINT, &oldint, NULL);
1407N/A if (oldalrm.sa_handler != SIG_IGN)
1407N/A sigaction(SIGALRM, &oldalrm, NULL);
1407N/A if (oldterm.sa_handler != SIG_IGN)
1407N/A sigaction(SIGTERM, &oldterm, NULL);
1407N/A }
1407N/A
1407N/A else {
1407N/A /* We come here from the siglongjmp in ast_signal_routine. */
1407N/A
1407N/A /* Mask SIGHUP, SIGINT, SIGALRM, SIGTERM. */
1407N/A
1407N/A sigprocmask(SIG_SETMASK, &oldprocmask, NULL);
1407N/A
1407N/A /* Restore the signals. */
1407N/A
1407N/A if (oldhup.sa_handler != SIG_IGN)
1407N/A sigaction(SIGHUP, &oldhup, NULL);
1407N/A if (oldint.sa_handler != SIG_IGN)
1407N/A sigaction(SIGINT, &oldint, NULL);
1407N/A if (oldalrm.sa_handler != SIG_IGN)
1407N/A sigaction(SIGALRM, &oldalrm, NULL);
1407N/A if (oldterm.sa_handler != SIG_IGN)
1407N/A sigaction(SIGTERM, &oldterm, NULL);
1407N/A
1407N/A /* Cause us to get the signal, when we unmask the signals. */
1407N/A
1407N/A kill(getpid(), signo);
1407N/A }
1407N/A
1407N/A ast_restore_palet();
1407N/A
1407N/A if (ast_unmap_mem(rp, GRAPHICS_ERR_MEMORY_MSG) != 0)
1407N/A return (-1);
1407N/A
1407N/A return (0);
1117N/A}
1117N/A
1117N/A
1117N/Avoid
1407N/Acheck_plane(
1407N/A register int const num_planes,
1407N/A register int const access_mode,
1407N/A register int const fb_pitch,
1407N/A register int const fb_height,
1407N/A register int const fb_width,
1407N/A register int const bytepp,
1407N/A register caddr_t const base)
1117N/A{
1407N/A register int x;
1407N/A register int y;
1407N/A register int complement;
1407N/A
1407N/A /* Set up raster for this plane group */
1407N/A
1407N/A init_data(num_planes);
1407N/A
1407N/A /* Cover each 64x64 chunk of screen space */
1407N/A
1407N/A y = 0;
1407N/A while (y < fb_height) {
1407N/A x = 0;
1407N/A while (x < fb_width) {
1407N/A if (x + 63 > fb_width)
1407N/A x = fb_width - 64;
1407N/A if (y + 63 > fb_height)
1407N/A y = fb_height - 64;
1407N/A
1407N/A /* Do each chunk twice - once normal, once complement */
1117N/A
1407N/A for (complement = B_FALSE;
1407N/A complement <= B_TRUE;
1407N/A complement++) {
1407N/A write_read(x, y,
1407N/A (boolean_t)complement,
1407N/A access_mode,
1407N/A B_TRUE,
1407N/A fb_pitch,
1407N/A bytepp,
1407N/A base) ||
1407N/A write_read(x, y,
1407N/A (boolean_t)complement,
1407N/A access_mode,
1407N/A B_FALSE,
1407N/A fb_pitch,
1407N/A bytepp,
1407N/A base);
1407N/A }
1407N/A
1407N/A /* Move over one 64x64 chunk */
1407N/A
1407N/A x += 64;
1407N/A }
1407N/A
1407N/A /* Move down one 64x64 chunk */
1407N/A
1407N/A y += 64;
1407N/A }
1407N/A}
1407N/A
1407N/A
1407N/Avoid
1407N/Ainit_data(
1407N/A register int const num_planes)
1407N/A{
1407N/A register int i;
1407N/A register int j;
1117N/A
1117N/A /* Get memory to store data */
1117N/A
1407N/A /* Write data to memory */
1117N/A
1407N/A for (i = 0; i < num_planes * 8; i++) {
1407N/A for (j = 0; j < 8; j++) {
1117N/A
1407N/A /* Figure out the value to write */
1117N/A
1407N/A data[i].val[j] = ((unsigned long long)
1407N/A test_data() << 32) | test_data();
1407N/A cdata[i].val[j] = ~data[i].val[j];
1407N/A }
1117N/A }
1407N/A}
1117N/A
1407N/A
1407N/A
1407N/Auint_t
1407N/Atest_data(
1407N/A void)
1407N/A{
1407N/A register uint_t ret;
1407N/A
1407N/A ret = (uint_t)mrand48();
1407N/A return (ret);
1407N/A}
1117N/A
1117N/A
1117N/Aboolean_t
1407N/Awrite_read(
1407N/A register int const xoff,
1407N/A register int const yoff,
1407N/A register boolean_t const complement,
1407N/A register int const access_mode,
1407N/A register boolean_t const pass,
1407N/A register int const fb_pitch,
1407N/A register int const bytepp,
1407N/A register caddr_t const base)
1117N/A{
1407N/A register MemType *const dp = complement ? cdata : data;
1407N/A register int const pitch = fb_pitch;
1407N/A register int x;
1407N/A register int y;
1407N/A register int i;
1407N/A register caddr_t mem_addr;
1407N/A register int subscr = 0;
1117N/A
1117N/A /* Write Data to Screen */
1407N/A
1117N/A for (y = yoff; y < yoff + 64; y++) {
1407N/A for (x = xoff * bytepp, i = 0;
1407N/A x < ((xoff + 64) * bytepp);
1407N/A x += access_mode, i++) {
1407N/A mem_addr = (y * pitch * bytepp) + x + base;
1407N/A
1407N/A /* Check which access mode to use for write */
1407N/A
1407N/A switch (access_mode) {
1407N/A case 8: /* long long (8-byte) access mode */
1407N/A *(uint64_t volatile *)mem_addr =
1407N/A dp[subscr].val[i];
1407N/A break;
1407N/A
1407N/A case 4: /* word (4-byte) access mode */
1407N/A *(uint32_t volatile *)mem_addr =
1407N/A dp[subscr].word[i];
1407N/A break;
1407N/A
1407N/A case 2: /* short (2-byte) access mode */
1407N/A *(uint16_t volatile *)mem_addr =
1407N/A dp[subscr].halfwd[i];
1407N/A break;
1407N/A
1407N/A default: /* default to byte access */
1407N/A *(uint8_t volatile *)mem_addr =
1407N/A dp[subscr].byte[i];
1407N/A break;
1407N/A }
1117N/A }
1407N/A subscr++;
1117N/A }
1117N/A
1117N/A /* Read the Data From the Screen */
1117N/A
1407N/A for (y = yoff; y < yoff + 64; y++) {
1407N/A for (x = xoff * bytepp, i = 0;
1407N/A x < ((xoff + 64) * bytepp);
1407N/A x += access_mode, i++) {
1407N/A mem_addr = (y * pitch * bytepp) + x + base;
1117N/A
1407N/A switch (access_mode) {
1407N/A case 8: /* long long (8-byte) access mode */
1407N/A rdval[0].val[i] =
1407N/A *(uint64_t volatile const *)mem_addr;
1407N/A break;
1117N/A
1407N/A case 4: /* word (4-byte) access mode */
1407N/A rdval[0].word[i] =
1407N/A *(uint32_t volatile const *)mem_addr;
1407N/A break;
1407N/A
1407N/A case 2: /* short (2-byte) access mode */
1407N/A rdval[0].halfwd[i] =
1407N/A *(uint16_t volatile const *)mem_addr;
1407N/A break;
1407N/A
1407N/A default: /* default to byte access */
1407N/A rdval[0].byte[i] =
1407N/A *(uint8_t volatile const *)mem_addr;
1407N/A break;
1407N/A }
1117N/A }
1117N/A
1117N/A /* TODO: verification */
1407N/A
1407N/A if (memcmp(rdval, dp[subscr].byte, 64 * bytepp) != 0) {
1407N/A switch (access_mode) {
1407N/A case 8: /* long long (8-byte) access mode */
1407N/A for (i = 0; i < (8 * bytepp); i++) {
1407N/A if (rdval[0].val[i] !=
1407N/A dp[subscr].val[i])
1407N/A return (B_FALSE);
1407N/A }
1407N/A break;
1407N/A
1407N/A case 4: /* word (4-byte) access mode */
1407N/A for (i = 0; i < (16 * bytepp); i++) {
1407N/A if (rdval[0].word[i] !=
1407N/A dp[subscr].word[i])
1407N/A return (B_FALSE);
1407N/A }
1407N/A break;
1407N/A
1407N/A case 2: /* short (2-byte) access mode */
1407N/A for (i = 0; i < (32 * bytepp); i++) {
1407N/A if (rdval[0].halfwd[i] !=
1407N/A dp[subscr].halfwd[i])
1407N/A return (B_FALSE);
1407N/A }
1407N/A break;
1407N/A
1407N/A default: /* default to byte access */
1407N/A for (i = 0; i < (64 * bytepp); i++) {
1407N/A if (rdval[0].byte[i] !=
1407N/A dp[subscr].byte[i])
1407N/A return (B_FALSE);
1407N/A }
1407N/A break;
1117N/A }
1117N/A }
1407N/A subscr++;
1117N/A }
1117N/A
1117N/A return (B_TRUE);
1407N/A}
1117N/A
1117N/A
1117N/A/* End of memory.c */