[BACK]Return to pdc.c CVS log [TXT][DIR] Up to [local] / sys / arch / hppa64 / stand / libsa

Annotation of sys/arch/hppa64/stand/libsa/pdc.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: pdc.c,v 1.1 2005/04/01 10:40:48 mickey Exp $  */
                      2:
                      3: /*
                      4:  * Copyright (c) 2005 Michael Shalayeff
                      5:  * All rights reserved.
                      6:  *
                      7:  * Permission to use, copy, modify, and distribute this software for any
                      8:  * purpose with or without fee is hereby granted, provided that the above
                      9:  * copyright notice and this permission notice appear in all copies.
                     10:  *
                     11:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     12:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     13:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     14:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     15:  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
                     16:  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
                     17:  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     18:  */
                     19: /*
                     20:  * Copyright 1996 1995 by Open Software Foundation, Inc.
                     21:  *              All Rights Reserved
                     22:  *
                     23:  * Permission to use, copy, modify, and distribute this software and
                     24:  * its documentation for any purpose and without fee is hereby granted,
                     25:  * provided that the above copyright notice appears in all copies and
                     26:  * that both the copyright notice and this permission notice appear in
                     27:  * supporting documentation.
                     28:  *
                     29:  * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
                     30:  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
                     31:  * FOR A PARTICULAR PURPOSE.
                     32:  *
                     33:  * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
                     34:  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
                     35:  * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
                     36:  * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
                     37:  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     38:  *
                     39:  */
                     40: /*
                     41:  * Copyright (c) 1990 mt Xinu, Inc.  All rights reserved.
                     42:  * Copyright (c) 1990 University of Utah.  All rights reserved.
                     43:  *
                     44:  * This file may be freely distributed in any form as long as
                     45:  * this copyright notice is included.
                     46:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     47:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     48:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     49:  *
                     50:  *     Utah $Hdr: pdc.c 1.8 92/03/14$
                     51:  */
                     52:
                     53: #include <sys/time.h>
                     54: #include "libsa.h"
                     55: #include <sys/reboot.h>
                     56: #include <sys/disklabel.h>
                     57:
                     58: #include <machine/trap.h>
                     59: #include <machine/pdc.h>
                     60: #include <machine/iomod.h>
                     61: #include <machine/nvm.h>
                     62: #include <machine/param.h>
                     63: #include <machine/cpufunc.h>
                     64:
                     65: #include "dev_hppa64.h"
                     66:
                     67: /*
                     68:  * Interface routines to initialize and access the PDC.
                     69:  */
                     70:
                     71: pdcio_t pdc;
                     72: int    pdcbuf[64] PDC_ALIGNMENT;/* PDC return buffer */
                     73: struct stable_storage sstor;   /* contents of Stable Storage */
                     74: int    sstorsiz;               /* size of Stable Storage */
                     75: struct bootdata bd;
                     76: int bdsize = sizeof(struct bootdata);
                     77:
                     78: /*
                     79:  * Initialize PDC and related variables.
                     80:  */
                     81: void
                     82: pdc_init()
                     83: {
                     84:        int err;
                     85:
                     86:        /*
                     87:         * Initialize important global variables (defined above).
                     88:         */
                     89:        pdc = (pdcio_t)(u_long)PAGE0->mem_pdc;
                     90:
                     91:        err = pdc_call(pdc, PDC_STABLE, PDC_STABLE_SIZE, pdcbuf, 0, 0);
                     92:        if (err >= 0) {
                     93:                sstorsiz = min(pdcbuf[0],sizeof(sstor));
                     94:                err = (*pdc)(PDC_STABLE, PDC_STABLE_READ, 0, &sstor, sstorsiz);
                     95:        }
                     96:
                     97:        /*
                     98:         * Now that we (may) have an output device, if we encountered
                     99:         * an error reading Stable Storage (above), let them know.
                    100:         */
                    101: #ifdef DEBUG
                    102:        if (debug && err)
                    103:                printf("Stable storage PDC_STABLE Read Ret'd %d\n", err);
                    104: #endif
                    105:
                    106:        /*
                    107:         * Clear the FAULT light (so we know when we get a real one)
                    108:         */
                    109:        pdc_call(pdc, PDC_CHASSIS, PDC_CHASSIS_DISP,
                    110:            PDC_OSTAT(PDC_OSTAT_BOOT) | 0xCEC0);
                    111: }
                    112:
                    113: /*
                    114:  * Generic READ/WRITE through IODC.  Takes pointer to PDC device
                    115:  * information, returns (positive) number of bytes actually read or
                    116:  * the (negative) error condition, or zero if at "EOF".
                    117:  */
                    118: int
                    119: iodcstrategy(devdata, rw, blk, size, buf, rsize)
                    120:        void *devdata;
                    121:        int rw;
                    122:        daddr_t blk;
                    123:        size_t size;
                    124:        void *buf;
                    125:        size_t *rsize;
                    126: {
                    127:        struct hppa_dev *dp = devdata;
                    128:        struct pz_device *pzdev = dp->pz_dev;
                    129:        iodcio_t iodc = (iodcio_t)(u_long)pzdev->pz_iodc_io;
                    130:        int     offset, xfer, ret;
                    131:
                    132: #ifdef PDCDEBUG
                    133:        if (debug)
                    134:                printf("iodcstrategy(%p, %s, %u, %u, %p, %p)\n", devdata,
                    135:                    rw==F_READ? "READ" : "WRITE", blk, size, buf, rsize);
                    136:
                    137:        if (debug > 1)
                    138:                PZDEV_PRINT(pzdev);
                    139: #endif
                    140:
                    141:        blk += dp->fsoff;
                    142:        blk <<= DEV_BSHIFT;
                    143:        if ((pzdev->pz_class & PCL_CLASS_MASK) == PCL_SEQU) {
                    144:                /* rewind and re-read to seek */
                    145:                if (blk < dp->last_blk) {
                    146: #ifdef PDCDEBUG
                    147:                        if (debug)
                    148:                                printf("iodc: rewind ");
                    149: #endif
                    150:                        if ((ret = ((iodcio_t)(long)pzdev->pz_iodc_io)(
                    151:                            pzdev->pz_hpa, IODC_IO_READ, pzdev->pz_spa,
                    152:                            pzdev->pz_layers, pdcbuf, 0, dp->buf, 0, 0)) < 0) {
                    153: #ifdef DEBUG
                    154:                                if (debug)
                    155:                                        printf("IODC_IO: %d\n", ret);
                    156: #endif
                    157:                                return (EIO);
                    158:                        } else {
                    159:                                dp->last_blk = 0;
                    160:                                dp->last_read = 0;
                    161:                        }
                    162:                }
                    163:
                    164: #ifdef PDCDEBUG
                    165:                if (debug)
                    166:                        printf("seek %d ", dp->last_blk);
                    167: #endif
                    168:                for (; (dp->last_blk + dp->last_read) <= blk;
                    169:                     dp->last_read = ret) {
                    170:                        twiddle();
                    171:                        dp->last_blk += dp->last_read;
                    172:                        if ((ret = (iodc)(pzdev->pz_hpa,
                    173:                            IODC_IO_READ, pzdev->pz_spa, pzdev->pz_layers,
                    174:                            pdcbuf, dp->last_blk, dp->buf, IODC_IOSIZ,
                    175:                            IODC_IOSIZ)) < 0) {
                    176: #ifdef DEBUG
                    177:                                if (debug)
                    178:                                        printf("IODC_IO: %d\n", ret);
                    179: #endif
                    180:                                return (EIO);
                    181:                        }
                    182:                        if ((ret = pdcbuf[0]) == 0)
                    183:                                break;
                    184: #ifdef PDCDEBUG
                    185:                        if (debug)
                    186:                                printf("-");
                    187: #endif
                    188:                }
                    189: #ifdef PDCDEBUG
                    190:                if (debug)
                    191:                        printf("> %d[%d]\n", dp->last_blk, dp->last_read);
                    192: #endif
                    193:        }
                    194:
                    195:        xfer = 0;
                    196:        /* see if we can scratch anything from buffer */
                    197:        if (dp->last_blk <= blk && (dp->last_blk + dp->last_read) > blk) {
                    198:                twiddle();
                    199:                offset = blk - dp->last_blk;
                    200:                xfer = min(dp->last_read - offset, size);
                    201:                size -= xfer;
                    202:                blk += xfer;
                    203: #ifdef PDCDEBUG
                    204:                if (debug)
                    205:                        printf("off=%d,xfer=%d,size=%d,blk=%d\n",
                    206:                            offset, xfer, size, blk);
                    207: #endif
                    208:                bcopy(dp->buf + offset, buf, xfer);
                    209:                buf += xfer;
                    210:        }
                    211:
                    212:        /*
                    213:         * double buffer it all the time, to cache
                    214:         */
                    215:        for (; size; size -= ret, buf += ret, blk += ret, xfer += ret) {
                    216:                offset = blk & IOPGOFSET;
                    217:                if ((ret = (iodc)(pzdev->pz_hpa,
                    218:                    (rw == F_READ? IODC_IO_READ: IODC_IO_WRITE),
                    219:                    pzdev->pz_spa, pzdev->pz_layers, pdcbuf,
                    220:                    blk - offset, dp->buf, IODC_IOSIZ, IODC_IOSIZ)) < 0) {
                    221: #ifdef DEBUG
                    222:                        if (debug)
                    223:                                printf("iodc_read(%d,%d): %d\n",
                    224:                                    blk - offset, IODC_IOSIZ, ret);
                    225: #endif
                    226:                        if (xfer)
                    227:                                break;
                    228:                        else
                    229:                                return (EIO);
                    230:                }
                    231:                if ((ret = pdcbuf[0]) <= 0)
                    232:                        break;
                    233:                dp->last_blk = blk - offset;
                    234:                dp->last_read = ret;
                    235:                if ((ret -= offset) > size)
                    236:                        ret = size;
                    237:                bcopy(dp->buf + offset, buf, ret);
                    238: #ifdef PDCDEBUG
                    239:                if (debug)
                    240:                        printf("read %d(%d,%d)@%x ", ret,
                    241:                            dp->last_blk, dp->last_read, (u_int)buf);
                    242: #endif
                    243:            }
                    244:
                    245: #ifdef PDCDEBUG
                    246:        if (debug)
                    247:                printf("\n");
                    248: #endif
                    249:
                    250:        if (rsize)
                    251:                *rsize = xfer;
                    252:        return (0);
                    253: }
                    254:
                    255: /*
                    256:  * Find a device with specified unit number
                    257:  * (any if unit == -1), and of specified class (PCL_*).
                    258:  */
                    259: struct pz_device *
                    260: pdc_findev(unit, class)
                    261:        int unit, class;
                    262: {
                    263:        static struct pz_device pz;
                    264:        int layers[sizeof(pz.pz_layers)/sizeof(pz.pz_layers[0])];
                    265:        iodcio_t iodc;
                    266:        int err = 0;
                    267:        u_int hpa, spa;
                    268:
                    269: #ifdef PDCDEBUG
                    270:        if (debug)
                    271:                printf("pdc_finddev(%d, %x)\n", unit, class);
                    272: #endif
                    273:        iodc = (iodcio_t)((u_long)PAGE0->mem_free + IODC_MAXSIZE);
                    274:        hpa = PAGE0->mem_boot.pz_hpa;
                    275:        spa = ((struct iomod *)(u_long)hpa)->io_spa;
                    276:
                    277:        /* quick hack for boot device */
                    278:        if (PAGE0->mem_boot.pz_class == class &&
                    279:            (unit == -1 || PAGE0->mem_boot.pz_layers[0] == unit)) {
                    280:
                    281:                bcopy (&PAGE0->mem_boot.pz_dp, &pz.pz_dp, sizeof(pz.pz_dp));
                    282:                bcopy (pz.pz_layers, layers, sizeof(layers));
                    283:                if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, pdcbuf, hpa,
                    284:                    IODC_INIT, iodc, IODC_MAXSIZE)) < 0) {
                    285: #ifdef DEBUG
                    286:                        if (debug)
                    287:                                printf("IODC_READ: %d\n", err);
                    288: #endif
                    289:                        return NULL;
                    290:                }
                    291:        } else {
                    292:                struct pdc_memmap memmap;
                    293:                struct iodc_data mptr;
                    294:                int i, stp;
                    295:
                    296:                for (i = 0; i < 0xf; i++) {
                    297:                        pz.pz_bc[0] = pz.pz_bc[1] =
                    298:                        pz.pz_bc[2] = pz.pz_bc[3] = -1;
                    299:                        pz.pz_bc[4] = 2;
                    300:                        pz.pz_bc[5] = 0;        /* core bus */
                    301:                        pz.pz_mod = i;
                    302:                        if ((pdc)(PDC_MEMMAP, PDC_MEMMAP_HPA, &memmap,
                    303:                            &pz.pz_dp) < 0)
                    304:                                continue;
                    305: #ifdef PDCDEBUG
                    306:                        if (debug)
                    307:                                printf("memap: %d.%d.%d, hpa=%x, mpgs=%x\n",
                    308:                                    pz.pz_bc[4], pz.pz_bc[5], pz.pz_mod,
                    309:                                    memmap.hpa, memmap.morepages);
                    310: #endif
                    311:                        hpa = memmap.hpa;
                    312:
                    313:                        if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, &pdcbuf, hpa,
                    314:                            IODC_DATA, &mptr, sizeof(mptr))) < 0) {
                    315: #ifdef DEBUG
                    316:                                if (debug)
                    317:                                        printf("IODC_DATA: %d\n", err);
                    318: #endif
                    319:                                continue;
                    320:                        }
                    321:
                    322:                        if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, pdcbuf, hpa,
                    323:                            IODC_INIT, iodc, IODC_MAXSIZE)) < 0) {
                    324: #ifdef DEBUG
                    325:                                if (debug)
                    326:                                        printf("IODC_READ: %d\n", err);
                    327: #endif
                    328:                                continue;
                    329:                        }
                    330:
                    331:                        stp = IODC_INIT_FIRST;
                    332:                        do {
                    333:                                if ((err = (iodc)(hpa, stp, spa, layers,
                    334:                                    pdcbuf, 0, 0, 0, 0)) < 0) {
                    335: #ifdef DEBUG
                    336:                                        if (debug && err != PDC_ERR_EOD)
                    337:                                                printf("IODC_INIT_%s: %d\n",
                    338:                                                    stp==IODC_INIT_FIRST?
                    339:                                                    "FIRST":"NEXT", err);
                    340: #endif
                    341:                                        break;
                    342:                                }
                    343: #ifdef PDCDEBUG
                    344:                                if (debug)
                    345:                                        printf("[%x,%x,%x,%x,%x,%x], "
                    346:                                            "[%x,%x,%x,%x,%x,%x]\n",
                    347:                                            pdcbuf[0], pdcbuf[1], pdcbuf[2],
                    348:                                            pdcbuf[3], pdcbuf[4], pdcbuf[5],
                    349:                                            layers[0], layers[1], layers[2],
                    350:                                            layers[3], layers[4], layers[5]);
                    351: #endif
                    352:                                stp = IODC_INIT_NEXT;
                    353:
                    354:                        } while (pdcbuf[1] != class &&
                    355:                                 unit != -1 && unit != layers[0]);
                    356:
                    357:                        if (err >= 0)
                    358:                                break;
                    359:                }
                    360:        }
                    361:
                    362:        if (err >= 0) {
                    363:                /* init device */
                    364:                if (0  && (err = (iodc)(hpa, IODC_INIT_DEV, spa,
                    365:                    layers, pdcbuf, 0, 0, 0, 0)) < 0) {
                    366: #ifdef DEBUG
                    367:                        if (debug)
                    368:                                printf("INIT_DEV: %d\n", err);
                    369: #endif
                    370:                        return NULL;
                    371:                }
                    372:
                    373:                /* read i/o entry code */
                    374:                if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, pdcbuf, hpa,
                    375:                    IODC_IO, iodc, IODC_MAXSIZE)) < 0) {
                    376: #ifdef DEBUG
                    377:                        if (debug)
                    378:                                printf("IODC_READ: %d\n", err);
                    379: #endif
                    380:                        return NULL;
                    381:                }
                    382:
                    383:                pz.pz_flags = 0;
                    384:                bcopy(layers, pz.pz_layers, sizeof(pz.pz_layers));
                    385:                pz.pz_hpa = hpa;
                    386: /* XXX         pz.pz_spa = spa; */
                    387:                pz.pz_iodc_io = (u_long)iodc;
                    388:                pz.pz_class = class;
                    389:
                    390:                return &pz;
                    391:        }
                    392:
                    393:        return NULL;
                    394: }
                    395:
                    396: static __inline void
                    397: fall(int c_base, int c_count, int c_loop, int c_stride, int data)
                    398: {
                    399:         int loop;                  /* Internal vars */
                    400:
                    401:         for (; c_count--; c_base += c_stride)
                    402:                 for (loop = c_loop; loop--; )
                    403:                        if (data)
                    404:                                fdce(0, c_base);
                    405:                        else
                    406:                                fice(0, c_base);
                    407: }
                    408:
                    409: /*
                    410:  * fcacheall - Flush all caches.
                    411:  *
                    412:  * This routine is just a wrapper around the real cache flush routine.
                    413:  */
                    414: struct pdc_cache pdc_cacheinfo PDC_ALIGNMENT;
                    415:
                    416: void
                    417: fcacheall()
                    418: {
                    419:        int err;
                    420:
                    421:         if ((err = (*pdc)(PDC_CACHE, PDC_CACHE_DFLT, &pdc_cacheinfo)) < 0) {
                    422: #ifdef DEBUG
                    423:                if (debug)
                    424:                        printf("fcacheall: PDC_CACHE failed (%d).\n", err);
                    425: #endif
                    426:                return;
                    427:         }
                    428: #if PDCDEBUG
                    429:        if (debug)
                    430:                printf("pdc_cache:\nic={%u,%x,%x,%u,%u,%u}\n"
                    431:                       "dc={%u,%x,%x,%u,%u,%u}\n",
                    432:                       pdc_cacheinfo.ic_size, *(u_int *)&pdc_cacheinfo.ic_conf,
                    433:                       pdc_cacheinfo.ic_base, pdc_cacheinfo.ic_stride,
                    434:                       pdc_cacheinfo.ic_count, pdc_cacheinfo.ic_loop,
                    435:                       pdc_cacheinfo.dc_size, *(u_int *)&pdc_cacheinfo.ic_conf,
                    436:                       pdc_cacheinfo.dc_base, pdc_cacheinfo.dc_stride,
                    437:                       pdc_cacheinfo.dc_count, pdc_cacheinfo.dc_loop);
                    438: #endif
                    439:         /*
                    440:          * Flush the instruction, then data cache.
                    441:          */
                    442:         fall(pdc_cacheinfo.ic_base, pdc_cacheinfo.ic_count,
                    443:             pdc_cacheinfo.ic_loop, pdc_cacheinfo.ic_stride, 0);
                    444:        sync_caches();
                    445:         fall(pdc_cacheinfo.dc_base, pdc_cacheinfo.dc_count,
                    446:             pdc_cacheinfo.dc_loop, pdc_cacheinfo.dc_stride, 1);
                    447:        sync_caches();
                    448: }

CVSweb