#include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef DDB #include #endif cons_decl(sacom); cons_decl(sacomfake); void sacominit(bus_space_tag_t bust, bus_addr_t busa, int speed); int sacomcnattach(bus_space_tag_t bust, bus_addr_t busa, int speed); void sacomfakecnattach(bus_addr_t addr); /* * Fake autoconf stuff. */ struct cfdriver sacom_cd = { NULL, "sacom", DV_TTY }; struct sacom_softc { struct device sc_dev; }; int sacom_match(struct device *parent, void *match, void *aux); void sacom_attach(struct device *parent, struct device *self, void *aux); struct cfattach sacom_ca = { sizeof(struct sacom_softc), sacom_match, sacom_attach, }; int sacom_match(struct device *parent, void *match, void *aux) { return (1); } void sacom_attach(struct device *parent, struct device *self, void *aux) { printf(": SA-11x0 UART\n"); return; } /* * Stuff for early sacom console support. */ bus_space_tag_t sacom_bust; bus_space_handle_t sacom_bush; bus_addr_t sacom_base; /* XXX for early sacom */ int sacom_speed; int sacom_attached; struct consdev sacom_consdev = { NULL /* probe */, NULL, /* init */ sacomcngetc, sacomcnputc, NULL /* poll */, NULL /* bell */, NODEV, CN_NORMAL }; /* fake one (to use in bootstrap) */ struct consdev sacom_fakeconsdev = { NULL /* probe */, NULL, /* init */ sacomfakecngetc, sacomfakecnputc, NULL /* poll */, NULL /* bell */, NODEV, CN_NORMAL }; void sacominit(bus_space_tag_t bust, bus_addr_t busa, int speed) { if (!sacom_attached && bus_space_map(bust, busa, 0x24, 0, &sacom_bush)) panic("sacomcninit: mapping failed"); sacom_bust = bust; sacom_attached = 1; sacom_speed = speed; } void sacomcninit(struct consdev *p) { sacominit(sacom_bust, sacom_bush, sacom_speed); } void sacomfakecnattach(bus_addr_t addr) { /* * XXX assume that loader (hpcboot) already set up UART3. * Just point cn_tab at our fake putc & getc routines. */ sacom_base = addr; cn_tab = &sacom_fakeconsdev; // sacom_attached = 1; } int sacomcnattach(bus_space_tag_t bust, bus_addr_t busa, int speed) { /* * Early console attachment. * Called from initarm() to print messages on boot. */ // int s = splhigh(); /* TODO: check state in which hpcboot leaves uart */ if (!sacom_attached) { sacominit(bust, busa, speed); cn_tab = &sacom_consdev; sacom_attached = 1; } // splx(s); return(0); } /* ARGSUSED */ int sacomcngetc(dev_t dev) { /* TODO */ #if 0 u_char stat; int c, s; #ifdef lint stat = dev; if (stat) return (0); #endif s = splhigh(); while (((stat = sacom_cn->sacom_lsr) & LSR_RXRDY) == 0) ; c = sacom_cn->sacom_data; stat = sacom_cn->sacom_iir; splx(s); return (c); #endif /* 0 */ return(0); } /* ARGSUSED */ int sacomfakecngetc(dev_t dev) { /* TODO */ return(0); } /* * Console kernel output character routine. */ /* ARGSUSED */ void sacomcnputc(dev_t dev, int c) { int timo; // int s = splhigh(); if (sacom_attached == 0) { /* XXX */ panic("sacomcnputc: write to unattached device"); } /* wait for any pending transmission to finish */ timo = 50000; while ((bus_space_read_4(sacom_bust, sacom_bush, SACOM_SR1) & SR1_TBY) == 1 && --timo) ; bus_space_write_4(sacom_bust, sacom_bush, SACOM_DR, c); /* wait for this transmission to complete */ timo = 1500000; while ((bus_space_read_4(sacom_bust, sacom_bush, SACOM_SR1) & SR1_TBY) == 1 && --timo) ; /* XXX clear just generated intrs */ // splx(s); } /* ARGSUSED */ void sacomfakecnputc(dev_t dev, int c) { int timo; /* wait for any pending transmission to finish */ timo = 50000; while (((*(volatile uint32_t *)(sacom_base + SACOM_SR1)) & SR1_TBY) == 1 && --timo) ; *(uint32_t *)(sacom_base + SACOM_DR) = c; /* wait for this transmission to complete */ timo = 1500000; while (((*(volatile uint32_t *)(sacom_base + SACOM_SR1)) & SR1_TBY) == 1 && --timo) ; }