📄 ns16552.h
字号:
/* * PC specific code for the ns16552. It includes support for the 2 built * in uarts plus up to 5 MP-008 8 uart ISA cards. */enum{ Maxcard= 5, /* max serial cards */ UartFREQ= 1843200, Serial= 0, Modem= 1,};#define uartwrreg(u,r,v) outb((u)->port + r, (u)->sticky[r] | (v))#define uartrdreg(u,r) inb((u)->port + r)void ns16552setup(ulong, ulong, char*, int);void ns16552special(int, int, Queue**, Queue**, int (*)(Queue*, int));void uartclock(void);/* * definition of an optional serial card */typedef struct Scard{ ISAConf; /* card configuration */ int first; /* number of first port */} Scard;static Scard *scard[Maxcard]; /* configs for the serial card *//* power management currently only makes sense on the AT&T safari */static voiduartpower(int dev, int onoff){ switch(dev){ case Modem: if((*arch->modempower)(onoff) < 0) print("can't turn %s modem speaker\n", onoff?"on":"off"); break; case Serial: if((*arch->serialpower)(onoff) < 0) print("can't turn %s serial port power\n", onoff?"on":"off"); break; }}/* * handle an interrupt to a single uart */static voidns16552intrx(Ureg*, void* arg){ ns16552intr((ulong)arg);}/* * interrupts from the multiport card, MP-008. A polling port * tells which of 8 devices interrupted. */static voidmp008intr(Ureg* ureg, void* arg){ int i, loops; uchar n; Scard *mp; mp = arg; for(loops = 0; loops < 1024; loops++){ n = ~inb(mp->mem); if(n == 0) return; for(i = 0; n; i++){ if(n & 1) ns16552intrx(ureg, (void*)(mp->first+i)); n >>= 1; } }}/* * install the uarts (called by reset) */voidns16552install(void){ int i, j, port, nscard; char *p, *q; Scard *sc; char name[NAMELEN]; static int already; if(already) return; already = 1; /* first two ports are always there and always the normal frequency */ if(ioalloc(0x3f8, 8, 0, "eia0") < 0) print("eia0: port %d in use\n", 0x3f8); ns16552setup(0x3F8, UartFREQ, "eia0", Ns550); intrenable(IrqUART0, ns16552intrx, (void*)0, BUSUNKNOWN, "eia0"); if(ioalloc(0x2F8, 8, 0, "eia1") < 0) print("eia1: port %d in use\n", 0x2F8); ns16552setup(0x2F8, UartFREQ, "eia1", Ns550); intrenable(IrqUART1, ns16552intrx, (void*)1, BUSUNKNOWN, "eia1"); addclock0link(uartclock); /* set up a serial console */ if(p = getconf("console")){ port = strtol(p, &q, 0); if(p != q && (port == 0 || port == 1)) ns16552special(port, 9600, &kbdq, &printq, kbdcr2nl); } /* the rest come out of plan9.ini */ nscard = 0; for(i = 0; i < Maxcard; i++){ sc = scard[nscard] = xalloc(sizeof(Scard)); if(isaconfig("serial", i, sc) == 0){ xfree(sc); scard[nscard] = 0; continue; } snprint(name, sizeof name, "eia%d00", nscard); if(cistrcmp(sc->type, "MP008") == 0){ /* * port gives base port address for uarts * irq is interrupt * mem is the polling port * size is the number of serial ports on the same polling port * freq is the baud rate generator frequency */ if(sc->size == 0) sc->size = 8; if(sc->freq == 0) sc->freq = UartFREQ; sc->first = nuart; if(ioalloc(sc->port, 8*sc->size, 0, name) < 0){ print("mp008: port %lud in use\n", sc->port); xfree(sc); scard[nscard] = 0; continue; } intrenable(sc->irq, mp008intr, sc, BUSUNKNOWN, name); port = sc->port; for(j=0; j < sc->size; j++){ sprint(name, "eia%d%2.2d", nscard, j); ns16552setup(port, sc->freq, name, Ns550); port += 8; } } else if(cistrcmp(sc->type, "turbo650") == 0){ /* * port gives base port address for the uart * irq is interrupt * freq is the baud rate generator frequency */ if(sc->freq == 0) sc->freq = UartFREQ*4; if(ioalloc(sc->port, 8, 0, name) < 0){ print("%s: port %lud in use\n", name, sc->port); xfree(sc); scard[nscard] = 0; continue; } ns16552setup(sc->port, sc->freq, name, Ns650); /* * multiply clock speed by 4 */ if(sc->mem == 0) outb(0x2c8, 0); else outb(sc->mem, 0); intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN, name); } else if(cistrcmp(sc->type, "com") == 0 && sc->port != 0x3F8 && sc->port != 0x2F8){ /* * port gives base port address for the uart * irq is interrupt * freq is the baud rate generator frequency */ if(sc->freq == 0) sc->freq = UartFREQ; if(ioalloc(sc->port, 8, 0, name) < 0){ print("%s: port %lud in use\n", name, sc->port); xfree(sc); scard[nscard] = 0; continue; } ns16552setup(sc->port, sc->freq, name, Ns550); intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN, name); } nscard++; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -