Annotation of qemu/roms/openbios/drivers/cuda.c, revision 1.1

1.1     ! root        1: #include "config.h"
        !             2: #include "libopenbios/bindings.h"
        !             3: #include "drivers/drivers.h"
        !             4: #include "libc/byteorder.h"
        !             5: #include "libc/vsprintf.h"
        !             6: 
        !             7: #include "macio.h"
        !             8: #include "cuda.h"
        !             9: 
        !            10: //#define DEBUG_CUDA
        !            11: #ifdef DEBUG_CUDA
        !            12: #define CUDA_DPRINTF(fmt, args...) \
        !            13:        do { printk("CUDA - %s: " fmt, __func__ , ##args); } while (0)
        !            14: #else
        !            15: #define CUDA_DPRINTF(fmt, args...) do { } while (0)
        !            16: #endif
        !            17: 
        !            18: #define IO_CUDA_OFFSET 0x00016000
        !            19: #define IO_CUDA_SIZE   0x00002000
        !            20: 
        !            21: /* VIA registers - spaced 0x200 bytes apart */
        !            22: #define RS              0x200           /* skip between registers */
        !            23: #define B               0               /* B-side data */
        !            24: #define A               RS              /* A-side data */
        !            25: #define DIRB            (2*RS)          /* B-side direction (1=output) */
        !            26: #define DIRA            (3*RS)          /* A-side direction (1=output) */
        !            27: #define T1CL            (4*RS)          /* Timer 1 ctr/latch (low 8 bits) */
        !            28: #define T1CH            (5*RS)          /* Timer 1 counter (high 8 bits) */
        !            29: #define T1LL            (6*RS)          /* Timer 1 latch (low 8 bits) */
        !            30: #define T1LH            (7*RS)          /* Timer 1 latch (high 8 bits) */
        !            31: #define T2CL            (8*RS)          /* Timer 2 ctr/latch (low 8 bits) */
        !            32: #define T2CH            (9*RS)          /* Timer 2 counter (high 8 bits) */
        !            33: #define SR              (10*RS)         /* Shift register */
        !            34: #define ACR             (11*RS)         /* Auxiliary control register */
        !            35: #define PCR             (12*RS)         /* Peripheral control register */
        !            36: #define IFR             (13*RS)         /* Interrupt flag register */
        !            37: #define IER             (14*RS)         /* Interrupt enable register */
        !            38: #define ANH             (15*RS)         /* A-side data, no handshake */
        !            39: 
        !            40: /* Bits in B data register: all active low */
        !            41: #define TREQ            0x08            /* Transfer request (input) */
        !            42: #define TACK            0x10            /* Transfer acknowledge (output) */
        !            43: #define TIP             0x20            /* Transfer in progress (output) */
        !            44: 
        !            45: /* Bits in ACR */
        !            46: #define SR_CTRL         0x1c            /* Shift register control bits */
        !            47: #define SR_EXT          0x0c            /* Shift on external clock */
        !            48: #define SR_OUT          0x10            /* Shift out if 1 */
        !            49: 
        !            50: /* Bits in IFR and IER */
        !            51: #define IER_SET         0x80            /* set bits in IER */
        !            52: #define IER_CLR         0               /* clear bits in IER */
        !            53: #define SR_INT          0x04            /* Shift register full/empty */
        !            54: 
        !            55: #define CUDA_BUF_SIZE 16
        !            56: 
        !            57: #define ADB_PACKET      0
        !            58: #define CUDA_PACKET     1
        !            59: 
        !            60: /* CUDA commands (2nd byte) */
        !            61: #define CUDA_GET_TIME                  0x03
        !            62: #define CUDA_SET_TIME                  0x09
        !            63: #define CUDA_POWERDOWN                  0x0a
        !            64: #define CUDA_RESET_SYSTEM               0x11
        !            65: 
        !            66: static uint8_t cuda_readb (cuda_t *dev, int reg)
        !            67: {
        !            68:            return *(volatile uint8_t *)(dev->base + reg);
        !            69: }
        !            70: 
        !            71: static void cuda_writeb (cuda_t *dev, int reg, uint8_t val)
        !            72: {
        !            73:            *(volatile uint8_t *)(dev->base + reg) = val;
        !            74: }
        !            75: 
        !            76: static void cuda_wait_irq (cuda_t *dev)
        !            77: {
        !            78:     int val;
        !            79: 
        !            80: //    CUDA_DPRINTF("\n");
        !            81:     for(;;) {
        !            82:         val = cuda_readb(dev, IFR);
        !            83:         cuda_writeb(dev, IFR, val & 0x7f);
        !            84:         if (val & SR_INT)
        !            85:             break;
        !            86:     }
        !            87: }
        !            88: 
        !            89: 
        !            90: 
        !            91: static int cuda_request (cuda_t *dev, uint8_t pkt_type, const uint8_t *buf,
        !            92:                          int buf_len, uint8_t *obuf)
        !            93: {
        !            94:     int i, obuf_len, val;
        !            95: 
        !            96:     cuda_writeb(dev, ACR, cuda_readb(dev, ACR) | SR_OUT);
        !            97:     cuda_writeb(dev, SR, pkt_type);
        !            98:     cuda_writeb(dev, B, cuda_readb(dev, B) & ~TIP);
        !            99:     if (buf) {
        !           100:         //CUDA_DPRINTF("Send buf len: %d\n", buf_len);
        !           101:         /* send 'buf' */
        !           102:         for(i = 0; i < buf_len; i++) {
        !           103:             cuda_wait_irq(dev);
        !           104:             cuda_writeb(dev, SR, buf[i]);
        !           105:             cuda_writeb(dev, B, cuda_readb(dev, B) ^ TACK);
        !           106:         }
        !           107:     }
        !           108:     cuda_wait_irq(dev);
        !           109:     cuda_writeb(dev, ACR, cuda_readb(dev, ACR) & ~SR_OUT);
        !           110:     cuda_readb(dev, SR);
        !           111:     cuda_writeb(dev, B, cuda_readb(dev, B) | TIP | TACK);
        !           112: 
        !           113:     obuf_len = 0;
        !           114:     if (obuf) {
        !           115:         cuda_wait_irq(dev);
        !           116:         cuda_readb(dev, SR);
        !           117:         cuda_writeb(dev, B, cuda_readb(dev, B) & ~TIP);
        !           118:         for(;;) {
        !           119:             cuda_wait_irq(dev);
        !           120:             val = cuda_readb(dev, SR);
        !           121:             if (obuf_len < CUDA_BUF_SIZE)
        !           122:                 obuf[obuf_len++] = val;
        !           123:             if (cuda_readb(dev, B) & TREQ)
        !           124:                 break;
        !           125:             cuda_writeb(dev, B, cuda_readb(dev, B) ^ TACK);
        !           126:         }
        !           127:         cuda_writeb(dev, B, cuda_readb(dev, B) | TIP | TACK);
        !           128: 
        !           129:         cuda_wait_irq(dev);
        !           130:         cuda_readb(dev, SR);
        !           131:     }
        !           132: //    CUDA_DPRINTF("Got len: %d\n", obuf_len);
        !           133: 
        !           134:     return obuf_len;
        !           135: }
        !           136: 
        !           137: 
        !           138: 
        !           139: static int cuda_adb_req (void *host, const uint8_t *snd_buf, int len,
        !           140:                          uint8_t *rcv_buf)
        !           141: {
        !           142:     uint8_t buffer[CUDA_BUF_SIZE], *pos;
        !           143: 
        !           144:  //   CUDA_DPRINTF("len: %d %02x\n", len, snd_buf[0]);
        !           145:     len = cuda_request(host, ADB_PACKET, snd_buf, len, buffer);
        !           146:     if (len > 1 && buffer[0] == ADB_PACKET) {
        !           147:         pos = buffer + 2;
        !           148:         len -= 2;
        !           149:     } else {
        !           150:         pos = buffer + 1;
        !           151:         len = -1;
        !           152:     }
        !           153:     memcpy(rcv_buf, pos, len);
        !           154: 
        !           155:     return len;
        !           156: }
        !           157: 
        !           158: 
        !           159: DECLARE_UNNAMED_NODE(ob_cuda, INSTALL_OPEN, sizeof(int));
        !           160: 
        !           161: static cuda_t *main_cuda;
        !           162: 
        !           163: static void
        !           164: ppc32_reset_all(void)
        !           165: {
        !           166:         uint8_t cmdbuf[2], obuf[64];
        !           167: 
        !           168:         cmdbuf[0] = CUDA_RESET_SYSTEM;
        !           169:         cuda_request(main_cuda, CUDA_PACKET, cmdbuf, sizeof(cmdbuf), obuf);
        !           170: }
        !           171: 
        !           172: static void
        !           173: ppc32_poweroff(void)
        !           174: {
        !           175:         uint8_t cmdbuf[2], obuf[64];
        !           176: 
        !           177:         cmdbuf[0] = CUDA_POWERDOWN;
        !           178:         cuda_request(main_cuda, CUDA_PACKET, cmdbuf, sizeof(cmdbuf), obuf);
        !           179: }
        !           180: 
        !           181: static void
        !           182: ob_cuda_initialize (int *idx)
        !           183: {
        !           184:        phandle_t ph=get_cur_dev();
        !           185:        int props[2];
        !           186: 
        !           187:        push_str("via-cuda");
        !           188:        fword("device-type");
        !           189: 
        !           190:        set_int_property(ph, "#address-cells", 1);
        !           191:         set_int_property(ph, "#size-cells", 0);
        !           192: 
        !           193:        set_property(ph, "compatible", "cuda", 5);
        !           194: 
        !           195:        props[0] = __cpu_to_be32(IO_CUDA_OFFSET);
        !           196:        props[1] = __cpu_to_be32(IO_CUDA_SIZE);
        !           197: 
        !           198:        set_property(ph, "reg", (char *)&props, sizeof(props));
        !           199: 
        !           200:        /* on newworld machines the cuda is on interrupt 0x19 */
        !           201: 
        !           202:        props[0] = 0x19;
        !           203:        props[1] = 0;
        !           204:        NEWWORLD(set_property(ph, "interrupts", (char *)props, sizeof(props)));
        !           205:        NEWWORLD(set_int_property(ph, "#interrupt-cells", 2));
        !           206: 
        !           207:        /* we emulate an oldworld hardware, so we must use
        !           208:         * non-standard oldworld property (needed by linux 2.6.18)
        !           209:         */
        !           210: 
        !           211:        OLDWORLD(set_int_property(ph, "AAPL,interrupts", 0x12));
        !           212: 
        !           213:         bind_func("ppc32-reset-all", ppc32_reset_all);
        !           214:         push_str("' ppc32-reset-all to reset-all");
        !           215:         fword("eval");
        !           216: }
        !           217: 
        !           218: static void
        !           219: ob_cuda_open(int *idx)
        !           220: {
        !           221:        RET(-1);
        !           222: }
        !           223: 
        !           224: static void
        !           225: ob_cuda_close(int *idx)
        !           226: {
        !           227: }
        !           228: 
        !           229: NODE_METHODS(ob_cuda) = {
        !           230:        { NULL,                 ob_cuda_initialize      },
        !           231:        { "open",               ob_cuda_open            },
        !           232:        { "close",              ob_cuda_close           },
        !           233: };
        !           234: 
        !           235: DECLARE_UNNAMED_NODE(rtc, INSTALL_OPEN, sizeof(int));
        !           236: 
        !           237: static void
        !           238: rtc_open(int *idx)
        !           239: {
        !           240:        RET(-1);
        !           241: }
        !           242: 
        !           243: /*
        !           244:  * get-time ( -- second minute hour day month year )
        !           245:  *
        !           246:  */
        !           247: 
        !           248: static const int days_month[12] =
        !           249:        { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        !           250: static const int days_month_leap[12] =
        !           251:        { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        !           252: 
        !           253: static inline int is_leap(int year)
        !           254: {
        !           255:        return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
        !           256: }
        !           257: 
        !           258: static  void
        !           259: rtc_get_time(int *idx)
        !           260: {
        !           261:         uint8_t cmdbuf[2], obuf[64];
        !           262:        ucell second, minute, hour, day, month, year;
        !           263:        uint32_t now;
        !           264:        int current;
        !           265:        const int *days;
        !           266: 
        !           267:         cmdbuf[0] = CUDA_GET_TIME;
        !           268:         cuda_request(main_cuda, CUDA_PACKET, cmdbuf, sizeof(cmdbuf), obuf);
        !           269: 
        !           270:        /* seconds since 01/01/1904 */
        !           271: 
        !           272:        now = (obuf[3] << 24) + (obuf[4] << 16) + (obuf[5] << 8) + obuf[6];
        !           273: 
        !           274:        second =  now % 60;
        !           275:        now /= 60;
        !           276: 
        !           277:        minute = now % 60;
        !           278:        now /= 60;
        !           279: 
        !           280:        hour = now % 24;
        !           281:        now /= 24;
        !           282: 
        !           283:        year = now * 100 / 36525;
        !           284:        now -= year * 36525 / 100;
        !           285:        year += 1904;
        !           286: 
        !           287:        days = is_leap(year) ?  days_month_leap : days_month;
        !           288: 
        !           289:        current = 0;
        !           290:        month = 0;
        !           291:        while (month < 12) {
        !           292:                if (now <= current + days[month]) {
        !           293:                        break;
        !           294:                }
        !           295:                current += days[month];
        !           296:                month++;
        !           297:        }
        !           298:        month++;
        !           299: 
        !           300:        day = now - current;
        !           301: 
        !           302:        PUSH(second);
        !           303:        PUSH(minute);
        !           304:        PUSH(hour);
        !           305:        PUSH(day);
        !           306:        PUSH(month);
        !           307:        PUSH(year);
        !           308: }
        !           309: 
        !           310: /*
        !           311:  * set-time ( second minute hour day month year -- )
        !           312:  *
        !           313:  */
        !           314: 
        !           315: static  void
        !           316: rtc_set_time(int *idx)
        !           317: {
        !           318:         uint8_t cmdbuf[5], obuf[3];
        !           319:        ucell second, minute, hour, day, month, year;
        !           320:        const int *days;
        !           321:        uint32_t now;
        !           322:        unsigned int nb_days;
        !           323:        int i;
        !           324: 
        !           325:        year = POP();
        !           326:        month = POP();
        !           327:        day = POP();
        !           328:        hour = POP();
        !           329:        minute = POP();
        !           330:        second = POP();
        !           331: 
        !           332:        days = is_leap(year) ?  days_month_leap : days_month;
        !           333:        nb_days = (year - 1904) * 36525 / 100 + day;
        !           334:        for (i = 0; i < month - 1; i++)
        !           335:                nb_days += days[i];
        !           336: 
        !           337:        now = (((nb_days * 24) + hour) * 60 + minute) * 60 + second;
        !           338: 
        !           339:         cmdbuf[0] = CUDA_SET_TIME;
        !           340:        cmdbuf[1] = now >> 24;
        !           341:        cmdbuf[2] = now >> 16;
        !           342:        cmdbuf[3] = now >> 8;
        !           343:        cmdbuf[4] = now;
        !           344: 
        !           345:         cuda_request(main_cuda, CUDA_PACKET, cmdbuf, sizeof(cmdbuf), obuf);
        !           346: }
        !           347: 
        !           348: NODE_METHODS(rtc) = {
        !           349:        { "open",               rtc_open                },
        !           350:        { "get-time",           rtc_get_time            },
        !           351:        { "set-time",           rtc_set_time            },
        !           352: };
        !           353: 
        !           354: static void
        !           355: rtc_init(char *path)
        !           356: {
        !           357:        phandle_t ph, aliases;
        !           358:        char buf[64];
        !           359: 
        !           360:         snprintf(buf, sizeof(buf), "%s/rtc", path);
        !           361:        REGISTER_NAMED_NODE(rtc, buf);
        !           362: 
        !           363:        ph = find_dev(buf);
        !           364:        set_property(ph, "device_type", "rtc", 4);
        !           365:        set_property(ph, "compatible", "rtc", 4);
        !           366: 
        !           367:        aliases = find_dev("/aliases");
        !           368:        set_property(aliases, "rtc", buf, strlen(buf) + 1);
        !           369: 
        !           370: }
        !           371: 
        !           372: cuda_t *cuda_init (const char *path, phys_addr_t base)
        !           373: {
        !           374:        cuda_t *cuda;
        !           375:        char buf[64];
        !           376:        phandle_t aliases;
        !           377: 
        !           378:        base += IO_CUDA_OFFSET;
        !           379:        CUDA_DPRINTF(" base=" FMT_plx "\n", base);
        !           380:        cuda = malloc(sizeof(cuda_t));
        !           381:        if (cuda == NULL)
        !           382:            return NULL;
        !           383: 
        !           384:        snprintf(buf, sizeof(buf), "%s/via-cuda", path);
        !           385:        REGISTER_NAMED_NODE(ob_cuda, buf);
        !           386: 
        !           387:        aliases = find_dev("/aliases");
        !           388:        set_property(aliases, "via-cuda", buf, strlen(buf) + 1);
        !           389: 
        !           390:        cuda->base = base;
        !           391:        cuda_writeb(cuda, B, cuda_readb(cuda, B) | TREQ | TIP);
        !           392: #ifdef CONFIG_DRIVER_ADB
        !           393:        cuda->adb_bus = adb_bus_new(cuda, &cuda_adb_req);
        !           394:        if (cuda->adb_bus == NULL) {
        !           395:            free(cuda);
        !           396:            return NULL;
        !           397:        }
        !           398:        adb_bus_init(buf, cuda->adb_bus);
        !           399: #endif
        !           400: 
        !           401:        rtc_init(buf);
        !           402: 
        !           403:         main_cuda = cuda;
        !           404: 
        !           405:        device_end();
        !           406:        bind_func("poweroff", ppc32_poweroff);
        !           407: 
        !           408:        return cuda;
        !           409: }

unix.superglobalmegacorp.com

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