/* * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * The contents of this file constitute Original Code as defined in and * are subject to the Apple Public Source License Version 1.1 (the * "License"). You may not use this file except in compliance with the * License. Please obtain a copy of the License at * http://www.apple.com/publicsource and read it before using this file. * * This Original Code and all software distributed under the License are * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* * This file contains firmware code. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern Boot_Video boot_video_info; Boot_Video dgVideo; extern GDWorkArea GratefulDebWork[]; typedef struct RuptCtr { /* Counts hardware interrupts */ struct GDpos { /* Screen position for Grateful Deb display */ unsigned short col; /* Column (-1 means no display) */ unsigned short row; /* Row */ } GDpos; unsigned int count; /* Count of interrupt */ unsigned int timed; /* If set, count updates at timed rate */ unsigned int lasttime; /* Low of timebase when last updated */ } RuptCtr; /* Window layout for Grateful Deb: * * 0 9 * * 0 Total Decrimenter * 1 DSI ISI * 2 System call External * 3 SIGP Floating point * 4 Program Alignment */ RuptCtr RuptCtrs[96] = { { { 0, 0}, 0, 1 }, /* Total interruptions */ { {-1, -1}, 0, 0 }, /* Reset */ { {-1, -1}, 0, 0 }, /* Machine check */ { { 0, 1}, 0, 1 }, /* DSIs */ { { 1, 1}, 0, 1 }, /* ISIs */ { { 1, 2}, 0, 1 }, /* Externals */ { { 1, 4}, 0, 0 }, /* Alignment */ { { 0, 4}, 0, 0 }, /* Program */ { { 1, 3}, 0, 0 }, /* Floating point */ { { 1, 0}, 0, 1 }, /* Decrementer */ { {-1, -1}, 0, 0 }, /* I/O error */ { {-1, -1}, 0, 0 }, /* Reserved */ { { 0, 2}, 0, 1 }, /* System call */ { {-1, -1}, 0, 0 }, /* Trace */ { {-1, -1}, 0, 0 }, /* Floating point assist */ { {-1, -1}, 0, 0 }, /* Performance monitor */ { {-1, -1}, 0, 0 }, /* VMX */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Instruction breakpoint */ { {-1, -1}, 0, 0 }, /* System management */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Trace */ { { 0, 3}, 0, 0 }, /* SIGP */ { {-1, -1}, 0, 0 }, /* Preemption */ { {-1, -1}, 0, 0 }, /* Context switch */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Special, update frequency controls */ /* Start of second processor counts */ { { 0, 0}, 0, 1 }, /* Total interruptions */ { {-1, -1}, 0, 0 }, /* Reset */ { {-1, -1}, 0, 0 }, /* Machine check */ { { 0, 1}, 0, 1 }, /* DSIs */ { { 1, 1}, 0, 1 }, /* ISIs */ { { 1, 2}, 0, 1 }, /* Externals */ { { 1, 4}, 0, 0 }, /* Alignment */ { { 0, 4}, 0, 0 }, /* Program */ { { 1, 3}, 0, 0 }, /* Floating point */ { { 1, 0}, 0, 1 }, /* Decrementer */ { {-1, -1}, 0, 0 }, /* I/O error */ { {-1, -1}, 0, 0 }, /* Reserved */ { { 0, 2}, 0, 1 }, /* System call */ { {-1, -1}, 0, 0 }, /* Trace */ { {-1, -1}, 0, 0 }, /* Floating point assist */ { {-1, -1}, 0, 0 }, /* Performance monitor */ { {-1, -1}, 0, 0 }, /* VMX */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Instruction breakpoint */ { {-1, -1}, 0, 0 }, /* System management */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Trace */ { { 0, 3}, 0, 0 }, /* SIGP */ { {-1, -1}, 0, 0 }, /* Preemption */ { {-1, -1}, 0, 0 }, /* Context switch */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 }, /* Reserved */ { {-1, -1}, 0, 0 } /* Special, update frequency controls */ }; void GratefulDebInit(bootBumbleC *boot_video_info) { /* Initialize the video debugger */ unsigned int fillframe[256]; unsigned int startpos, startbyte, windowleft, newwidth, i, j, startword, oldwidth, nrmlgn; unsigned int nwords, *byteleft, lstlgn, pixlgn, bytelgn; if(!boot_video_info) { /* Are we disabling it? GratefulDebWork[0].GDready = 0; /* Disable output */ return; } nrmlgn = (9 * GDfontsize) * (boot_video_info->v_depth / 8); /* Get the normal column size in bytes */ lstlgn = (((8 * GDfontsize) + (GDfontsize >> 1)) * boot_video_info->v_depth) / 8; /* Same as normal, but with 1/2 character space */ nrmlgn = (nrmlgn + 31) & -32; /* Round to a line */ bytelgn = (nrmlgn * (GDdispcols - 1)) + lstlgn; /* Length in bytes */ pixlgn = bytelgn / (boot_video_info->v_depth / 8); /* Number of pixels wide */ startbyte = (boot_video_info->v_width * (boot_video_info->v_depth / 8)) - bytelgn; /* Get the starting byte unaligned */ startpos = boot_video_info->v_width - pixlgn; /* Starting pixel position */ startbyte += (unsigned int)boot_video_info->v_baseAddr & 31; /* Add the extra to cache boundary in frame buffer */ startbyte &= -32; /* Make sure it's on a cache line for speed */ startbyte += (unsigned int)boot_video_info->v_baseAddr & 31; /* Subtract the extra to cache boundary in frame buffer */ windowleft = startbyte - (((GDfontsize / 2) * boot_video_info->v_depth) / 8); /* Back up a half character */ windowleft &= -4; /* Make sure it is on a word boundary */ newwidth = windowleft / (boot_video_info->v_depth / 8); /* Get the new pixel width of screen */ oldwidth = boot_video_info->v_width; /* Save the old width */ // boot_video_info->v_width = newwidth; /* Set the new width */ nwords = oldwidth - newwidth; /* See how much to fill in pixels */ nwords = nwords / (32 / boot_video_info->v_depth); /* Get that in bytes */ startword = (newwidth + 3) / 4; /* Where does it start? */ byteleft = (unsigned int *)(boot_video_info->v_baseAddr + windowleft); /* Starting place */ for (i=0; i < nwords; i++) byteleft[i] = 0; /* Set the row to all black */ byteleft = (unsigned int *)(boot_video_info->v_baseAddr + windowleft + (boot_video_info->v_rowBytes * 1)); /* Starting place */ for (i=0; i < nwords; i++) byteleft[i] = 0; /* Set the row to all black */ byteleft = (unsigned int *)(boot_video_info->v_baseAddr + windowleft + (boot_video_info->v_rowBytes * (boot_video_info->v_height - 2))); /* Starting place */ for (i=0; i < nwords; i++) byteleft[i] = 0; /* Set the row to all black */ byteleft = (unsigned int *)(boot_video_info->v_baseAddr + windowleft + (boot_video_info->v_rowBytes * (boot_video_info->v_height - 1))); /* Starting place */ for (i=0; i < nwords; i++) byteleft[i] = 0; /* Set the row to all black */ for (i=0; i < nwords; i++) fillframe[i] = 0xFFFFFFFF; /* Set the row to all white */ if(boot_video_info->v_depth == 8) { /* See if 8 bits a pixel */ fillframe[0] = 0x0000FFFF; /* Make left border */ fillframe[nwords - 1] = 0xFFFF0000; /* Make right border */ } else if(boot_video_info->v_depth == 16) { /* See if 16 bits a pixel */ fillframe[0] = 0x00000000; /* Make left border */ fillframe[nwords - 1] = 0x00000000; /* Make right border */ } else { fillframe[0] = 0x00000000; /* Make left border */ fillframe[1] = 0x00000000; /* Make left border */ fillframe[nwords - 1] = 0x00000000; /* Make right border */ fillframe[nwords - 2] = 0x00000000; /* Make right border */ } byteleft = (unsigned int *)(boot_video_info->v_baseAddr + windowleft + (boot_video_info->v_rowBytes * 2)); /* Place to start filling */ for(i=2; i < (boot_video_info->v_height - 2); i++) { /* Fill the rest */ for(j=0; jv_rowBytes); /* Next row */ } for(i=0; i<2; i++) { /* Initialize both (for now) processor areas */ GratefulDebWork[i].GDtop = 2 + (GDfontsize / 2) + (i * 18 * GDfontsize); GratefulDebWork[i].GDleft = 2 + startpos + (GDfontsize / 2); GratefulDebWork[i].GDtopleft = boot_video_info->v_baseAddr + startbyte + (GratefulDebWork[i].GDtop * boot_video_info->v_rowBytes); GratefulDebWork[i].GDrowbytes = boot_video_info->v_rowBytes; GratefulDebWork[i].GDrowchar = boot_video_info->v_rowBytes * (GDfontsize + (GDfontsize / 4)); GratefulDebWork[i].GDdepth = boot_video_info->v_depth; GratefulDebWork[i].GDcollgn = nrmlgn; // RuptCtrs[(48*i)+47].timed = gPEClockFrequencyInfo.timebase_frequency_hz >> 4; /* (Update every 16th of a second (16 fps) */ RuptCtrs[(48*i)+47].timed = gPEClockFrequencyInfo.timebase_frequency_hz >> 3; /* (Update every 8th of a second (8 fps) */ // RuptCtrs[(48*i)+47].timed = gPEClockFrequencyInfo.timebase_frequency_hz >> 2; /* (Update every 4th of a second (4 fps) */ // RuptCtrs[(48*i)+47].timed = gPEClockFrequencyInfo.timebase_frequency_hz >> 1; /* (Update every 2th of a second (2 fps) */ // RuptCtrs[(48*i)+47].timed = gPEClockFrequencyInfo.timebase_frequency_hz >> 0; /* (Update every 1 second (1 fps) */ sync(); GratefulDebWork[i].GDready = 1; /* This one's all ready */ } } void debugNoop(void); void debugNoop(void) { /* This does absolutely nothing */ return; }