Annotation of Gnu-Mach/chips/pm_misc.c, revision 1.1.1.1

1.1       root        1: /* 
                      2:  * Mach Operating System
                      3:  * Copyright (c) 1991,1990,1989 Carnegie Mellon University
                      4:  * All Rights Reserved.
                      5:  * 
                      6:  * Permission to use, copy, modify and distribute this software and its
                      7:  * documentation is hereby granted, provided that both the copyright
                      8:  * notice and this permission notice appear in all copies of the
                      9:  * software, derivative works or modified versions, and any portions
                     10:  * thereof, and that both notices appear in supporting documentation.
                     11:  * 
                     12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     15:  * 
                     16:  * Carnegie Mellon requests users of this software to return to
                     17:  * 
                     18:  *  Software Distribution Coordinator  or  [email protected]
                     19:  *  School of Computer Science
                     20:  *  Carnegie Mellon University
                     21:  *  Pittsburgh PA 15213-3890
                     22:  * 
                     23:  * any improvements or extensions that they make and grant Carnegie Mellon
                     24:  * the rights to redistribute these changes.
                     25:  */
                     26: /*
                     27:  *     File: pm_misc.c
                     28:  *     Author: Alessandro Forin, Carnegie Mellon University
                     29:  *     Date:   9/90
                     30:  *
                     31:  *     Driver for the VFB01/02 Mono/Color framebuffer (pmax)
                     32:  *     Hardware-independent operations, mostly shared with
                     33:  *     the CFB driver (see each individual function header),
                     34:  *     and possibly others.
                     35:  */
                     36: 
                     37: 
                     38: #include <platforms.h>
                     39: 
                     40: #include <fb.h>
                     41: 
                     42: #if    defined(DECSTATION) || defined(FLAMINGO)
                     43: #include <cfb.h>
                     44: #include <mfb.h>
                     45: #include <xcfb.h>
                     46: #include <sfb.h>
                     47: #define        NPM     (NFB+NCFB+NMFB+NXCFB+NSFB)
                     48: #endif /*DECSTATION*/
                     49: 
                     50: #ifdef VAXSTATION
                     51: #define        NPM     (NFB)
                     52: #endif /*VAXSTATION*/
                     53: 
                     54: 
                     55: #if    (NPM > 0)
                     56: 
                     57: #include <mach/vm_param.h>             /* PAGE_SIZE */
                     58: #include <device/device_types.h>
                     59: #include <vm/vm_map.h>                 /* kernel_pmap */
                     60: 
                     61: #include <chips/screen_defs.h>
                     62: #include <chips/pm_defs.h>
                     63: 
                     64: 
                     65: #ifdef DECSTATION
                     66: #define        machine_btop    mips_btop
                     67: #define MONO_BM                (256*1024)
                     68: #endif /*DECSTATION*/
                     69: 
                     70: #ifdef VAXSTATION
                     71: #define        machine_btop    vax_btop
                     72: /*
                     73:        For now we use the last page of the frame for
                     74:        the user_info structure.
                     75: */
                     76: #define MONO_BM                (256*1024-PAGE_SIZE)
                     77: #endif /*VAXSTATION*/
                     78: 
                     79: #ifdef FLAMINGO
                     80: #define        machine_btop    alpha_btop
                     81: #define MONO_BM                (256*1024)
                     82: #define        LOG2_SIZEOF_LONG        3       /* 64bit archies */
                     83: #endif /* FLAMINGO */
                     84: 
                     85: #ifndef        LOG2_SIZEOF_LONG
                     86: #define        LOG2_SIZEOF_LONG        2       /* 32bit archies */
                     87: #endif
                     88: 
                     89: 
                     90: /* Hardware state */
                     91: pm_softc_t     pm_softc_data[NPM];
                     92: 
                     93: pm_softc_t*
                     94: pm_alloc(
                     95:        int             unit,
                     96:        char            *cur,
                     97:        unsigned char   *fb,
                     98:        unsigned char   *pl)
                     99: {
                    100:        pm_softc_t     *pm = &pm_softc_data[unit];
                    101: 
                    102:        pm->cursor_registers    = cur;
                    103:        pm->framebuffer         = fb;
                    104:        pm->plane_mask          = pl;
                    105:        pm->vdac_registers      = 0;    /* later, if ever */
                    106: 
                    107:        screen_attach(unit, (char *) pm);
                    108: 
                    109:        return pm;
                    110: }
                    111: 
                    112: 
                    113: /*
                    114:  * Routine to paint a char on a simple framebuffer.
                    115:  * This is common to the pm, fb and cfb drivers.
                    116:  */
                    117: pm_char_paint(
                    118:        screen_softc_t  sc,
                    119:        int             c,
                    120:        int             row,
                    121:        int             col)
                    122: {
                    123:        register int    incr;
                    124:        int             line_size;
                    125:        register unsigned char  *font, *bmap;
                    126:        pm_softc_t      *pm = (pm_softc_t*)sc->hw_state;
                    127: 
                    128:        /*
                    129:         * Here are the magic numbers that drive the loops below:
                    130:         *      incr            bytes between scanlines of the glyph
                    131:         *      line_size       bytes in a row, using the system font
                    132:         *
                    133:         * This code has been optimized to avoid multiplications,
                    134:         * and is therefore much less obvious than it could be.
                    135:         */
                    136:        if (sc->flags & MONO_SCREEN) {
                    137:                /*
                    138:                 * B&W screen: 1 bit/pixel
                    139:                 *      incr --> 1 * BytesPerLine, with possible stride
                    140:                 */
                    141:                incr = sc->frame_scanline_width >> 3;
                    142:        } else {
                    143:                /*
                    144:                 * Color screen: 8 bits/pixel
                    145:                 *      incr --> 8 * BytesPerLine, with possible stride
                    146:                 */
                    147:                incr = sc->frame_scanline_width;
                    148:                col <<= 3;
                    149:        }
                    150: 
                    151:        /* not all compilers are smart about multiply by 15 */
                    152: #if    (KfontHeight==15)
                    153: #      define TIMES_KfontHeight(w)     (((w)<<4)-(w))
                    154: #else
                    155: #      define TIMES_KfontHeight(w)     ((w)*KfontHeight)
                    156: #endif
                    157:        line_size = TIMES_KfontHeight(incr);
                    158: 
                    159:        bmap = pm->framebuffer + col + (row * line_size);
                    160:        font = &kfont_7x14[ (int)(c - ' ') * 15];
                    161:        if (sc->flags & MONO_SCREEN) {
                    162:                /*
                    163:                 * Unroll simple loops, take note of common cases
                    164:                 */
                    165:                if (sc->standout) {
                    166: #                      define mv()     *bmap = ~*font++; bmap += incr;
                    167:                        mv();mv();mv();mv();mv();mv();mv();mv();
                    168:                        mv();mv();mv();mv();mv();mv();mv();
                    169: #                      undef   mv
                    170:                } else if (c == ' ') {
                    171: #                      define mv()     *bmap = 0; bmap += incr;
                    172:                        mv();mv();mv();mv();mv();mv();mv();mv();
                    173:                        mv();mv();mv();mv();mv();mv();mv();
                    174: #                      undef   mv
                    175:                } else {
                    176: #                      define mv()     *bmap = *font++; bmap += incr;
                    177:                        mv();mv();mv();mv();mv();mv();mv();mv();
                    178:                        mv();mv();mv();mv();mv();mv();mv();
                    179: #                      undef   mv
                    180:                }
                    181:        } else {
                    182:                /*
                    183:                 * 8 bits per pixel --> paint one byte per each font bit.
                    184:                 * In order to spread out the 8 bits of a glyph line over
                    185:                 * the 64 bits per scanline use a simple vector multiply,
                    186:                 * taking 4 bits at a time to get the two resulting words
                    187:                 */
                    188:                static unsigned int spread[16] = {
                    189:                        0x00000000, 0x00000001, 0x00000100, 0x00000101,
                    190:                        0x00010000, 0x00010001, 0x00010100, 0x00010101,
                    191:                        0x01000000, 0x01000001, 0x01000100, 0x01000101,
                    192:                        0x01010000, 0x01010001, 0x01010100, 0x01010101,
                    193:                };
                    194:                register int    rev_video = sc->standout;
                    195:                register int    j;
                    196:                for (j = 0; j < KfontHeight; j++) {
                    197:                        register unsigned char c = *font++;
                    198:                        if (rev_video) c = ~c;
                    199: #if    (LOG2_SIZEOF_LONG==3)
                    200:                        *((long*)bmap) =  (long)spread[ c & 0xf ] |
                    201:                                        ((long)(spread[ (c>>4) & 0xf ]) << 32);
                    202: #else
                    203:                        ((int*)bmap)[0] = spread[ c & 0xf ];
                    204:                        ((int*)bmap)[1] = spread[ (c>>4) & 0xf ];
                    205: #endif
                    206:                        bmap += incr;
                    207:                }
                    208:        }
                    209: }
                    210: 
                    211: /*
                    212:  * Delete the line at the given row.
                    213:  * This is common to the pm, fb and cfb drivers.
                    214:  */
                    215: pm_remove_line(
                    216:        screen_softc_t  sc,
                    217:        short           row)
                    218: {
                    219:        register long   *dest, *src;
                    220:        register long   *end;
                    221:        register long   temp0,temp1,temp2,temp3;
                    222:        register long   i, scaninc, blockcnt;
                    223:        long            line_size, incr;
                    224:        unsigned char   *framebuffer;
                    225:        pm_softc_t      *pm = (pm_softc_t*)sc->hw_state;
                    226:        long            CharRows, CharCols;
                    227: 
                    228:        CharRows = sc->up->max_row;
                    229:        CharCols = sc->up->max_col;
                    230:        framebuffer = pm->framebuffer;
                    231: 
                    232:        /* Inner loop works 4 long words at a time (writebuffer deep) */
                    233: #      define BlockSizeShift   (2+LOG2_SIZEOF_LONG)
                    234: 
                    235:        /*  To copy one (MONO) line, we need to iterate this many times */
                    236: #      define Blocks    (CharCols>>BlockSizeShift)
                    237: 
                    238:        /*  Skip this many bytes to get to the next line */
                    239: #      define Slop(w)   ((w) - (blockcnt<<BlockSizeShift))
                    240: 
                    241:        if (sc->flags & MONO_SCREEN) {
                    242:                blockcnt = Blocks;
                    243:                /* See comments in pm_char_paint() */
                    244:                incr = sc->frame_scanline_width >> 3;
                    245:        } else {
                    246:                blockcnt = Blocks << 3;
                    247:                /* See comments in pm_char_paint() */
                    248:                incr = sc->frame_scanline_width;
                    249:        }
                    250:        line_size = TIMES_KfontHeight(incr);
                    251: 
                    252:        scaninc = (Slop(incr)) >> LOG2_SIZEOF_LONG;     /* pointers are long* */
                    253: 
                    254:        dest = (long *)(framebuffer + row * line_size);
                    255:        src  = (long *)((char*)dest + line_size);
                    256:        end  = (long *)(framebuffer + CharRows * line_size);
                    257:        while (src < end) {
                    258:                i = 0;
                    259:                do {
                    260:                        temp0 = src[0];
                    261:                        temp1 = src[1];
                    262:                        temp2 = src[2];
                    263:                        temp3 = src[3];
                    264:                        dest[0] = temp0;
                    265:                        dest[1] = temp1;
                    266:                        dest[2] = temp2;
                    267:                        dest[3] = temp3;
                    268:                        dest += 4;
                    269:                        src += 4;
                    270:                        i++;
                    271:                } while (i < blockcnt);
                    272:                src += scaninc;
                    273:                dest += scaninc;
                    274:        }
                    275: 
                    276:        /* Now zero out the last line */
                    277:        bzero(framebuffer + (CharRows - 1) * line_size,  line_size);
                    278: 
                    279:        ascii_screen_rem_update(sc, row);
                    280: }
                    281: 
                    282: 
                    283: /*
                    284:  * Open a new blank line at the given row.
                    285:  * This is common to the pm, fb and cfb drivers.
                    286:  */
                    287: pm_insert_line(
                    288:        screen_softc_t  sc,
                    289:        short           row)
                    290: {
                    291:        register long   *dest, *src;
                    292:        register long   *end;
                    293:        register long   temp0,temp1,temp2,temp3;
                    294:        register long   i, scaninc, blockcnt;
                    295:        long            line_size, incr;
                    296:        unsigned char   *framebuffer;
                    297:        pm_softc_t      *pm = (pm_softc_t*)sc->hw_state;
                    298:        long            CharRows, CharCols;
                    299: 
                    300:        CharRows = sc->up->max_row;
                    301:        CharCols = sc->up->max_col;
                    302: 
                    303:        framebuffer = pm->framebuffer;
                    304: 
                    305:        /* See above for comments */
                    306:        if (sc->flags & MONO_SCREEN) {
                    307:                blockcnt = Blocks;
                    308:                /* See comments in pm_char_paint() */
                    309:                incr = sc->frame_scanline_width >> 3;
                    310:        } else {
                    311:                blockcnt = Blocks << 3;
                    312:                /* See comments in pm_char_paint() */
                    313:                incr = sc->frame_scanline_width;
                    314:        }
                    315:        line_size = TIMES_KfontHeight(incr);
                    316: 
                    317:        scaninc = Slop(incr) + ((2 * blockcnt) << BlockSizeShift);
                    318:        scaninc >>= LOG2_SIZEOF_LONG;           /* pointers are long* */
                    319:        dest = (long *)(framebuffer + (CharRows - 1) * line_size);
                    320:        src  = (long *)((char*)dest - line_size);
                    321:        end  = (long *)(framebuffer + row * line_size);
                    322:        while (src >= end) {
                    323:                i = 0;
                    324:                do {
                    325:                        temp0 = src[0];
                    326:                        temp1 = src[1];
                    327:                        temp2 = src[2];
                    328:                        temp3 = src[3];
                    329:                        dest[0] = temp0;
                    330:                        dest[1] = temp1;
                    331:                        dest[2] = temp2;
                    332:                        dest[3] = temp3;
                    333:                        dest += 4;
                    334:                        src += 4;
                    335:                        i++;
                    336:                } while (i < blockcnt);
                    337:                src -= scaninc;
                    338:                dest -= scaninc;
                    339:        }
                    340: 
                    341:        /* Now zero out the line being opened */
                    342:        bzero(framebuffer + row * line_size, line_size);
                    343: 
                    344:        ascii_screen_ins_update(sc, row);
                    345: }
                    346: 
                    347: #undef Slop
                    348: 
                    349: 
                    350: /*
                    351:  * Initialize screen parameters in the
                    352:  * user-mapped descriptor.
                    353:  * This is common to various drivers.
                    354:  */
                    355: pm_init_screen_params(
                    356:        screen_softc_t  sc,
                    357:        user_info_t     *up)
                    358: {
                    359:        register int    vis_x, vis_y;
                    360: 
                    361:        up->frame_scanline_width = sc->frame_scanline_width;
                    362:        up->frame_height = sc->frame_height;
                    363: 
                    364:        vis_x = sc->frame_visible_width;
                    365:        vis_y = sc->frame_visible_height;
                    366: 
                    367:        up->max_x               = vis_x;
                    368:        up->max_y               = vis_y;
                    369:        up->max_cur_x           = vis_x - 1;
                    370:        up->max_cur_y           = vis_y - 1;
                    371:        up->min_cur_x           = -15;
                    372:        up->min_cur_y           = -15;
                    373:        up->max_row             = vis_y / KfontHeight;
                    374:        up->max_col             = vis_x / KfontWidth;
                    375: 
                    376:        up->version             = 11;
                    377: 
                    378:        up->mouse_threshold     = 4;    
                    379:        up->mouse_scale         = 2;
                    380: 
                    381:        up->dev_dep_2.pm.tablet_scale_x = ((vis_x - 1) * 1000) / 2200;
                    382:        up->dev_dep_2.pm.tablet_scale_y = ((vis_y - 1) * 1000) / 2200;
                    383: }
                    384: 
                    385: /*
                    386:  * Clear the screen
                    387:  * Used by pm, fb and cfb
                    388:  */
                    389: pm_clear_bitmap(
                    390:        screen_softc_t  sc)
                    391: {
                    392:        pm_softc_t      *pm = (pm_softc_t *) sc->hw_state;
                    393:        unsigned int    screen_size;
                    394: 
                    395:        /* Do not touch the non visible part */
                    396:        screen_size = sc->frame_scanline_width * sc->frame_visible_height;
                    397:        blkclr((char *)pm->framebuffer,
                    398:                  (sc->flags & MONO_SCREEN) ? (screen_size>>3) : screen_size);
                    399: 
                    400:        /* clear ascii screenmap */
                    401:        ascii_screen_fill(sc, ' ');
                    402: }
                    403: 
                    404: 
                    405: /*
                    406:  * Size of the user-mapped structure
                    407:  * Used by both pm and cfb
                    408:  */
                    409: pm_mem_need()
                    410: {
                    411:        return USER_INFO_SIZE;
                    412: }
                    413: 
                    414: /*
                    415:  * Device-specific get status.
                    416:  * Used by fb and cfb also.
                    417:  */
                    418: pm_get_status(
                    419:        screen_softc_t  sc,
                    420:        dev_flavor_t    flavor,
                    421:        dev_status_t    status,
                    422:        natural_t       *status_count)
                    423: {
                    424:        if (flavor == SCREEN_GET_OFFSETS) {
                    425:                unsigned        *offs = (unsigned *) status;
                    426: 
                    427:                offs[0] = PM_SIZE(sc);          /* virtual size */
                    428:                offs[1] = 0;                    /* offset of user_info_t */
                    429:                *status_count = 2;
                    430:                return D_SUCCESS;
                    431:        } else
                    432:                return D_INVALID_OPERATION;
                    433: }
                    434: 
                    435: /*
                    436:  * Driver-specific set status
                    437:  * Only partially used by fb and cfb.
                    438:  */
                    439: pm_set_status(
                    440:        screen_softc_t  sc,
                    441:        dev_flavor_t    flavor,
                    442:        dev_status_t    status,
                    443:        natural_t       status_count)
                    444: {
                    445:        switch (flavor) {
                    446:        case SCREEN_ADJ_MAPPED_INFO: {
                    447:                unsigned        user_addr = *(unsigned *) status;
                    448:                user_info_t     *up = sc->up;
                    449: 
                    450:                /* Make it point to the event_queue, in user virtual */
                    451:                up->evque.events = (screen_event_t *)(user_addr +
                    452:                        ((char*)up->event_queue - (char*)up));
                    453: 
                    454:                /* Make it point to the point_track, in user virtual */
                    455:                up->evque.track = (screen_timed_point_t *)(user_addr +
                    456:                        ((char*)up->point_track - (char*)up));
                    457: 
                    458:                up->dev_dep_1.pm.planemask = (unsigned char *)(user_addr + USER_INFO_SIZE);
                    459: 
                    460:                up->dev_dep_1.pm.bitmap = up->dev_dep_1.pm.planemask + PMASK_SIZE;
                    461: 
                    462:                break;
                    463:        }
                    464: 
                    465:        case SCREEN_LOAD_CURSOR: {
                    466: 
                    467:                sc->flags |= SCREEN_BEING_UPDATED;
                    468:                dc503_load_cursor(sc->hw_state, (unsigned short*)status);
                    469:                sc->flags &= ~SCREEN_BEING_UPDATED;
                    470: 
                    471:                break;
                    472:        }
                    473: 
                    474: #ifdef DECSTATION
                    475:        case SCREEN_SET_CURSOR_COLOR: {
                    476:                pm_softc_t              *pm = (pm_softc_t*) sc->hw_state;
                    477: 
                    478:                sc->flags |= SCREEN_BEING_UPDATED;
                    479:                bt478_cursor_color (pm->vdac_registers, (cursor_color_t*) status);
                    480:                sc->flags &= ~SCREEN_BEING_UPDATED;
                    481: 
                    482:                break;
                    483:        }
                    484:             
                    485:        case SCREEN_SET_CMAP_ENTRY: {
                    486:                pm_softc_t              *pm = (pm_softc_t*) sc->hw_state;
                    487:                color_map_entry_t       *e = (color_map_entry_t*) status;
                    488: 
                    489:                if (e->index < 256) {
                    490:                        sc->flags |= SCREEN_BEING_UPDATED;
                    491:                        bt478_load_colormap_entry( pm->vdac_registers, e->index, &e->value);
                    492:                        sc->flags &= ~SCREEN_BEING_UPDATED;
                    493:                }
                    494: 
                    495:                break;
                    496:        }
                    497: #endif /*DECSTATION*/
                    498:        default:
                    499:                return D_INVALID_OPERATION;
                    500:        }
                    501:        return D_SUCCESS;
                    502: }
                    503: 
                    504: /*
                    505:  * Map pages to user space
                    506:  */
                    507: vm_offset_t pm_map_page_empty = (vm_offset_t) 0;
                    508: 
                    509: integer_t
                    510: pm_map_page(
                    511:        screen_softc_t  sc,
                    512:        vm_offset_t     off,
                    513:        int             prot)
                    514: {
                    515:        int             bitmapsize;
                    516:        integer_t       addr;
                    517:        pm_softc_t      *pm = (pm_softc_t *)sc->hw_state;
                    518:        extern vm_offset_t      pmap_extract( pmap_t map, vm_offset_t addr);
                    519: 
                    520:        bitmapsize = BITMAP_SIZE(sc);
                    521: 
                    522: #define        OFF0    USER_INFO_SIZE                  /* user mapped info */
                    523: #define        OFF1    OFF0+PMASK_SIZE                 /* plane mask register */
                    524: #define        OFF2    OFF1+bitmapsize                 /* frame buffer mem */
                    525: 
                    526:        if (off < OFF0)
                    527: #ifdef DECSTATION
                    528:                addr = kvtophys(sc->up);
                    529: #else
                    530:                addr = (integer_t) pmap_extract(kernel_pmap,
                    531:                                                (vm_offset_t)sc->up);
                    532: #endif
                    533:        else
                    534:        if (off < OFF1) {
                    535: #ifdef VAXSTATION
                    536:                if (pm_map_page_empty == 0) {
                    537:                        pm_map_page_empty = vm_page_grab_phys_addr();
                    538:                }
                    539:                addr = (integer_t)pmap_extract(kernel_pmap, pm_map_page_empty);
                    540: #else
                    541:                addr = (integer_t) pm->plane_mask;
                    542: #endif
                    543:                off -= OFF0;
                    544:        } else
                    545:        if (off < OFF2) {
                    546: #ifdef DECSTATION
                    547:                addr = (integer_t)pm->framebuffer;
                    548: #else
                    549:                addr = (integer_t)pmap_extract(kernel_pmap,
                    550:                                               (vm_offset_t)pm->framebuffer);
                    551: #endif
                    552:                off -= OFF1;
                    553:        } else 
                    554:                return D_INVALID_SIZE;  /* ??? */
                    555: 
                    556:        addr = machine_btop(addr + off);
                    557:        return (addr);
                    558: }
                    559: 
                    560: 
                    561: /*
                    562:  *-----------------------------------------------------------
                    563:  *     The rest of this file is stricly pmax/pvax-specific
                    564:  *-----------------------------------------------------------
                    565:  */
                    566: #if    (NFB > 0)
                    567: 
                    568: /*
                    569:  * Do what's needed when the X server exits
                    570:  */
                    571: pm_soft_reset(
                    572:        screen_softc_t  sc)
                    573: {
                    574:        pm_softc_t      *pm = (pm_softc_t*) sc->hw_state;
                    575:        user_info_t     *up = sc->up;
                    576: 
                    577:        /*
                    578:         * Restore params in mapped structure
                    579:         */
                    580:        pm_init_screen_params(sc, up);
                    581:        up->row = up->max_row - 2;
                    582:        dc503_init(pm);
                    583: 
                    584: #ifdef DECSTATION
                    585:        if (sc->flags & MONO_SCREEN)
                    586:                bt478_init_bw_map(pm->vdac_registers, pm->plane_mask);
                    587:        else
                    588:                bt478_init_color_map(pm->vdac_registers, pm->plane_mask);
                    589: #endif /*DECSTATION*/
                    590: }
                    591: #endif /* NFB > 0 */
                    592: 
                    593: 
                    594: #endif /* NPM > 0 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.