Annotation of qemu/roms/openbios/drivers/cuda.c, revision 1.1.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.