📄 hdl_uti.c
字号:
#ifndef lintstatic char sccsid[] = "@(#)hdl_uti.c 1.1 92/07/30 Copyr 1990 Sun Micro";#endif/* * Copyright (c) 1990 by Sun Microsystems, Inc. */#include <stdio.h>#include <math.h>#include <signal.h>#include <sys/types.h>#include <sys/file.h>#include <sys/ioctl.h>#include <sbusdev/gtreg.h>#include <varargs.h>#include <pixrect/pixrect_hs.h>#include <sdrtns.h> /* sdrtns.h should always be included */#include <gtmcb.h>#include <hk_public.h>#include <hk_comm.h>#include <gttest.h>#include <errmsg.h>#undef DEBUG/* Some predefined constants */#define DISPLAY_X 0 /* display x start */#define DISPLAY_Y 0 /* display y start */#define DISPLAY_WIDTH 1024 /* display width */#define DISPLAY_HEIGHT 1024 /* display height */#define MAX_VM_SIZE 0x13b000 /* Max size for DL + CTX + Stack */#define SCRATCH_BUFFER_SIZE 256 /* Size of scratch buffer */#define BG_R 0.0 /* Default background color */#define BG_G 0.0#define BG_B 0.0#define DEF_CLUT HK_DEFAULT_CLUT /* Default CLUT */#define FE_DELAY 12000 /* wait for FE 30 secs */externint sys_nerr;externint errno;externchar *sys_errlist[];int fastclear_set = HK_FCS_NONE; /* Static variables */ static Pixrect *pr; /* Pixrect pointer to be used throughout this program */static wid; /* Unique WID for HDL files */static unsigned *base_vm; /* Pointer to VM */static unsigned *vm; /* Pointer to next available VM */static unsigned vm_size; /* Size of virtual memory (in bytes) */static int verbose = FALSE; /* Indicates verbose messages */static int finished = 0; /* Display list completion */static int hawk_opened = 0; /* TRUE if hawk device already opened */ /* Pointers to Hawk flag words */static unsigned *vcom_host_s; /* Flag: Host to FE (signal handler) */static unsigned *vcom_host_u; /* Flag: Host to FE (user) */static unsigned *vcom_hawk_u; /* Flag: FE to host (user) */ /* Pointer to communication message control block */static Hkvc_umcb *user_mcb_ptr; /* user */ /* User context and display list data */static Hk_context *dl_ctx; /* Ptr to test display list ctx */static unsigned *fcbg; /* Pointer to fastclear color data in the display list to fast clear the screen */static unsigned *imgbuf; /* Pointer to the image buffer in the display list to fast clear the screen */static unsigned *ovlbuf; /* Pointer to the overlay buffer in the display list to fast clear the screen */static unsigned *fcs_fcbg; /* Pointer to the fast clear set # in the display list to fast clear the screen */static unsigned *fcs_wlut; /* Pointer to the fast clear set # in the display list to fast clear the screen */static unsigned *wid_entry; /* Pointer to the wid entry in the display list to fast clear the screen */static Hk_window_boundary *window_boundary; /* Window boundary */static unsigned *clearscreen_dl; /* clear screen display list ptr *//* error message */staticchar errtxt[256]; /* status at the time of interrupt */staticunsigned status;/* dpc at the time of interrupt */staticunsigned dpc;/* error code at the time of interrupt */staticint error = 0;staticint screen_x = DISPLAY_X;staticint screen_y = DISPLAY_Y;staticint screen_width = DISPLAY_WIDTH;staticint screen_height = DISPLAY_HEIGHT;staticint delay;staticint fbmode = -1;staticunsigned int fb_regs[32];staticint fb_saved=0;staticint dev_fd = -1;/**********************************************************************/static voiduser_signal_handler()/**********************************************************************//* Interupt handler for display list. Handles only TRAP 0 for the time being. */{ char *hk_error_string(); char *diag_escape_error_string(); int save_cmd; unsigned inst_err = 0, exp_inst, *iptr; func_name = "user_signal_handler"; TRACE_IN status = user_mcb_ptr->status; dpc = user_mcb_ptr->dpc; iptr = (unsigned *) dpc; error = user_mcb_ptr->errorcode;#ifdef DEBUG printf("*** BEFORE error ***\n"); printf("user mcb: gt_stopped=0x%x status=0x%x, dpc=0x%x, errorcode=0x%x, command=0x%x\n", user_mcb_ptr->gt_stopped, status, dpc, error, user_mcb_ptr->command); printf("trap_instruction = 0x%x host instruction = 0x%x gt_flags=0x%x instruction_count=0x%x\n", user_mcb_ptr->trap_instruction, *iptr, user_mcb_ptr->gt_flags, user_mcb_ptr->instruction_count);#endif DEBUG if (status & HKUVS_ERROR_CONDITION) { fb_send_message(SKIP_ERROR, ERROR, DLXERR_ERROR_CONDITION, error, (error < 0) ? diag_escape_error_string(error) : hk_error_string(error)); inst_err = 1;#ifdef DEBUG printf("*** AFTER error ***\n"); printf("user mcb: gt_stopped=0x%x status=0x%x, dpc=0x%x, errorcode=0x%x, command=0x%x\n", user_mcb_ptr->gt_stopped, status, dpc, error, user_mcb_ptr->command); printf("trap_instruction = 0x%x host instruction = 0x%x gt_flags=0x%x instruction_count=0x%x\n", user_mcb_ptr->trap_instruction, *iptr, user_mcb_ptr->gt_flags, user_mcb_ptr->instruction_count);#endif DEBUG /* verify dpc is within valid context range */ if ((iptr >= base_vm) & (iptr <= (base_vm + (vm_size/sizeof(unsigned))))) { exp_inst = *iptr; fb_send_message(SKIP_ERROR, ERROR, DLXERR_ERR_INSTRUCTION, dpc, exp_inst, user_mcb_ptr->trap_instruction); } else fb_send_message(SKIP_ERROR, ERROR, DLXERR_DPC_OUT_OF_RANGE, dpc); } else if (status & HKUVS_INSTRUCTION_TRAP) { if (user_mcb_ptr->trap_instruction != (HK_OP_TRAP << HK_OP_POS)) { fb_send_message(SKIP_ERROR, ERROR, DLXERR_UNKNOWN_TRAP_INSTRUCTION, user_mcb_ptr->trap_instruction, (HK_OP_TRAP << HK_OP_POS)); } } else { fb_send_message(SKIP_ERROR, ERROR, DLXERR_NOT_TRAP_INSTRUCTION, error, (error < 0) ? diag_escape_error_string(error) : hk_error_string(error)); } /* Flush everything to allow access to context and frame buffer */ save_cmd = user_mcb_ptr->command; user_mcb_ptr->command = HKUVC_FLUSH_RENDERING_PIPE | HKUVC_FLUSH_FULL_CONTEXT | HKUVC_PAUSE_WITHOUT_INTERRUPT; *vcom_host_s = 1; /* Tell Front End to do it */#ifdef DEBUG printf("*** FLUSH in user_signal_handler() ***\n"); printf("user mcb: gt_stopped=0x%x status=0x%x, dpc=0x%x, errorcode=0x%x, command=0x%x\n", user_mcb_ptr->gt_stopped, status, dpc, error, user_mcb_ptr->command); printf("trap_instruction = 0x%x gt_flags=0x%x instruction_count=0x%x\n", user_mcb_ptr->trap_instruction, user_mcb_ptr->gt_flags, user_mcb_ptr->instruction_count);#endif DEBUG delay = FE_DELAY; while (*vcom_host_s && (delay-- >= 0)) usleep(10); /* Wait for completion */ if (delay < 0) { dump_status(); fb_send_message(HAWK_FATAL_ERROR, FATAL, DLXERR_FE_TIMEOUT); } user_mcb_ptr->command = save_cmd; if (inst_err) { /* stop if FE detects an error condition */ dump_status(); fb_send_message(HAWK_FATAL_ERROR, FATAL, DLXERR_USER_TEST_ABORTED); } else finished = 1; /* Tell the main loop that the display list has been traversed */ TRACE_OUT} /* End of user_signal_handler *//**********************************************************************/open_hawk()/**********************************************************************//* Initialize the Hawk Subsystem, returns 1 on success and 0 on failure. */{ extern Pixrect *open_pr_device(); int i; int op; unsigned *build_clearscreen_ctx(); unsigned *ptr; struct gt_connect conn; unsigned *dummy_vm; func_name = "open_hawk"; TRACE_IN/* Open Hawk (get the kernel connections) */ if (hawk_opened) { TRACE_OUT return 1; } /* clear WID plane */ pr = open_pr_device(); if (pr == NULL) { TRACE_OUT return 0; } (void)pr_clear_all(pr); wid = wid_alloc(pr, FB_WID_DBL_24); pr_set_planes(pr, PIXPG_WID, PIX_ALL_PLANES); op = PIX_SRC | PIX_COLOR(wid); op = pr_clear(pr, op); close_pr_device(); if (hk_open()) { fb_send_message(SKIP_ERROR, ERROR, DLXERR_HK_OPEN_FAILED); TRACE_OUT return 0; }/* vm_size must include everything we put in the memory */ vm_size = MAX_VM_SIZE; vm = (unsigned *) hk_mmap((char *) 0, vm_size); if (vm == NULL) { TRACE_OUT return 0; } base_vm = vm;/* Build user MCB */ user_mcb_ptr = (Hkvc_umcb *) vm; vm += sizeof(Hkvc_umcb)/sizeof(unsigned); ptr = (unsigned *) user_mcb_ptr; for (i = 0; i < (sizeof(Hkvc_umcb) / sizeof(unsigned)); i++) *ptr++ = 0; /* Clear out all words *//* Set up window boundaries for all display lists */ window_boundary = (Hk_window_boundary *) vm; vm += sizeof(Hk_window_boundary)/sizeof(unsigned);/* Initialize the window_boundary */ window_boundary->xleft = screen_x; window_boundary->ytop = screen_y; window_boundary->width = screen_width; window_boundary->height = screen_height; /* reserve static space for fast clear */ clearscreen_dl = vm; vm = build_clearscreen_ctx(); /* reserve static space for common context */ dl_ctx = (Hk_context *) vm; /* intialise the ctx */ (void)init_dl_ctx(); /* reserve static space for test hdl files to be loaded */ vm += sizeof(Hk_context)/sizeof(unsigned); /* vm will not be changed any more from now on *//* Build a dummy dl which does nothing */ dummy_vm = vm; /* use dummy vm and keep the original vm */ dl_ctx->risc_regs[HK_RISC_SP] = (int) (base_vm + (vm_size/sizeof(unsigned))); dl_ctx->dpc = (unsigned) dummy_vm; dl_ctx->window_bg_color.r = BG_R; dl_ctx->window_bg_color.g = BG_G; dl_ctx->window_bg_color.b = BG_B; dl_ctx->s.current_wid = wid; /* dl_ctx->s.wid_clip_mask = 0x000; dl_ctx->s.wid_write_mask = 0x3ff; */ /* if (screen_height > screen_width) { dl_ctx->s.view.vt[HKM_1_1] = (float) screen_width / (float) screen_height; } else { dl_ctx->s.view.vt[HKM_0_0] = (float) screen_height / (float) screen_width; } dl_ctx->fast_clear_set = fastclear_set; */ dl_ctx->s.z_buffer_update = HK_Z_UPDATE_ALL; dl_ctx->draw_buffer = HK_BUFFER_A; /* *dummy_vm++ = ((HK_OP_UPDATE_LUT << HK_OP_POS) | (HK_UPDATE_FCBG << HK_SO_POS) | (HK_AM_IMMEDIATE << HK_AM_POS)); *dummy_vm++ = fastclear_set; *dummy_vm++ = ((int)(BG_B * 255.0) << 16) | ((int)(BG_G * 255.0) << 8) | (int)(BG_R * 255.0); *dummy_vm++ = (HK_OP_WINDOW_CLEAR << HK_OP_POS); *dummy_vm++ = ((HK_OP_UPDATE_LUT << HK_OP_POS) | (HK_UPDATE_WLUT << HK_SO_POS) | (HK_AM_IMMEDIATE << HK_AM_POS)); *dummy_vm++ = wid; *dummy_vm++ = 0x3ff; *dummy_vm++ = HK_BUFFER_A; *dummy_vm++ = HK_BUFFER_A; *dummy_vm++ = HK_24BIT; *dummy_vm++ = DEF_CLUT; *dummy_vm++ = fastclear_set; */ *dummy_vm++ = (HK_OP_TRAP << HK_OP_POS); user_mcb_ptr->magic = HK_UMCB_MAGIC; user_mcb_ptr->version = HK_UMCB_VERSION; user_mcb_ptr->context = (unsigned *) dl_ctx; user_mcb_ptr->command = HKUVC_LOAD_CONTEXT; /* Don't pause == go *//* Set up a signal handler (must come before hk_connect) */ (void)signal(SIGXCPU, user_signal_handler); /* Get the MCB and context connected to Hawk */ conn.gt_pmsgblk = user_mcb_ptr; if (hk_connect(&conn) < 0) { fb_send_message(SKIP_ERROR, ERROR, DLXERR_CONNECT); TRACE_OUT return 0;; } vcom_host_u = conn.gt_puvcr; vcom_host_s = conn.gt_psvcr;#ifdef DEBUG [ printf("**** open_hawk() Testing hawk ready ****\n");#endif DEBUG ] delay = FE_DELAY; /* Make sure Hawk is ready */ while (*vcom_host_u && (delay-- >= 0)) usleep(10); if (delay < 0) { dump_status(); fb_send_message(HAWK_FATAL_ERROR, FATAL, DLXERR_FE_TIMEOUT); } /* Make Hawk travese dummy display list once */ *vcom_host_u = 1;#ifdef DEBUG [ printf("**** open_hawk() Traverse dummy display list ****\n");#endif DEBUG ] delay = FE_DELAY; while (!finished && (delay-- >= 0)) usleep(10); /* Wait for interrupt */ if (delay < 0) { dump_status(); fb_send_message(HAWK_FATAL_ERROR, FATAL, DLXERR_FE_TIMEOUT); } finished = 0; hawk_opened = 1; /* Hawk is now ready for use */ TRACE_OUT return 1;}/**********************************************************************/unsigned *build_clearscreen_ctx()/**********************************************************************/{ unsigned *cs_dl; func_name = "build_clearscreen_ctx"; TRACE_IN cs_dl = clearscreen_dl;/* Prepare to clear the full screen */ *cs_dl++ = ((HK_OP_UPDATE_LUT << HK_OP_POS) | (HK_UPDATE_FCBG << HK_SO_POS) | (HK_AM_IMMEDIATE << HK_AM_POS)); fcs_fcbg = cs_dl++; fcbg = cs_dl++; *cs_dl++ = (HK_OP_WINDOW_CLEAR << HK_OP_POS); *cs_dl++ = ((HK_OP_UPDATE_LUT << HK_OP_POS) | (HK_UPDATE_WLUT << HK_SO_POS) | (HK_AM_IMMEDIATE << HK_AM_POS)); wid_entry = cs_dl++; /* Entry */ *cs_dl++ = 0x1f; /* Mask */ imgbuf = cs_dl++; /* Image buffer */ ovlbuf = cs_dl++; /* Overlay buffer */ *cs_dl++ = HK_24BIT; /* Plane_group */ *cs_dl++ = DEF_CLUT; /* CLUT */ fcs_wlut = cs_dl++; *cs_dl++ = (HK_OP_TRAP << HK_OP_POS); TRACE_OUT return cs_dl;}/**********************************************************************/char *exec_dl(dl_file)/**********************************************************************/char *dl_file;{ char *exec_dl_op(); int wait; char *res; func_name = "exec_dl"; TRACE_IN wait = 1; res = exec_dl_op(dl_file, wait); TRACE_OUT return res;}/**********************************************************************/char *exec_dl_nowait(dl_file)/**********************************************************************/char *dl_file;{ char *exec_dl_op(); int wait; char *res; func_name = "exec_dl_nowait"; TRACE_IN wait = 0; res = exec_dl_op(dl_file, wait); TRACE_OUT return res;}/**********************************************************************/char *exec_dl_op(dl_file, wait)/**********************************************************************/char *dl_file;int wait;/* loads display list into the vm and starts the display list */{ char *hk_error_string(); char *diag_escape_error_string(); FILE *fd = (FILE *)0; unsigned *dl_vm; /* Pointer to available VM for test display list */ int dl_size;/* Size in bytes of the display list */ func_name = "exec_dl_op"; TRACE_IN error = 0; /* intialise the ctx */ (void)init_dl_ctx(); dl_vm = vm;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -