static inline unsigned char uread(int uart, unsigned int reg) { register unsigned char val; if (uart == 0) { inport_byte(COM1_BASE_IO+reg, val); } else { inport_byte(COM2_BASE_IO+reg, val); } return val; }
uint32_t mc146818a_get_register( uint32_t ulCtrlPort, uint8_t ucRegNum ) { uint8_t val; uint8_t tmp; outport_byte( ulCtrlPort, ucRegNum ); inport_byte( 0x84, tmp ); /* Hack a delay to give chip time to settle */ inport_byte( ulCtrlPort+1, val ); inport_byte( 0x84, tmp ); /* Hack a delay to give chip time to settle */ return val; }
void DEFUN_VOID(_Console_Initialize) { register unsigned8 ignored; /* FORCE technical support mentioned that it may be necessary to read the DUSCC RX_BUFFER port four times to remove all junk. This code is a little more paranoid. */ inport_byte( RX_BUFFER, ignored ); inport_byte( RX_BUFFER, ignored ); inport_byte( RX_BUFFER, ignored ); inport_byte( RX_BUFFER, ignored ); inport_byte( RX_BUFFER, ignored ); }
uint8_t com_get_register(uint32_t addr,uint8_t i) { register uint8_t val; inport_byte( (addr + i),val ); return val; }
static bool pc386_ide_status_busy (uint32_t port, volatile uint32_t timeout, uint8_t* status_val, pc386_ide_sleeper sleeper) { volatile uint8_t status; int polls; do { polls = 500; while (polls) { inport_byte (port + IDE_REGISTER_STATUS, status); if ((status & IDE_REGISTER_STATUS_BSY) == 0) { *status_val = status; return true; } polls--; } if (timeout) { timeout--; pc386_ide_sleep (sleeper); } } while (timeout); *status_val = status; return false; }
int Timer_read() { register uint32_t clicks; register uint32_t total; /* outport_byte( TBCR, 0x00 ); stop the timer -- not needed on intel */ outport_byte ( TMRCON, 0x40 ); /* latch the count */ inport_byte ( TMR1, clicks ); /* read the count */ total = Ttimer_val + 250 - clicks; /* outport_byte( TBCR, 0x00 ); initial value */ /* outport_byte( IERA, 0x40 ); disable interrupt */ /* ??? Is "do not restore old vector" causing problems? */ if ( Timer_driver_Find_average_overhead == 1 ) return total; /* in one microsecond units */ else { if ( total < LEAST_VALID ) return 0; /* below timer resolution */ return (total - AVG_OVERHEAD); } }
static inline uint8_t BSP_i8259a_irq_in_service_reg(uint32_t ioport) { uint8_t isr; outport_byte(ioport, PIC_OCW3_SEL | PIC_OCW3_RR | PIC_OCW3_RIS); inport_byte(ioport, isr); outport_byte(ioport, PIC_OCW3_SEL | PIC_OCW3_RR); return isr; }
/*-------------------------------------------------------------------------+ | Function: rtcin | Description: Perform action on RTC and return its result. | Global Variables: None. | Arguments: what - what to write to RTC port (what to do). | Returns: result received from RTC port after action performed. +--------------------------------------------------------------------------*/ static inline uint8_t rtcin(uint8_t what) { uint8_t r; outport_byte(IO_RTC, what); inport_byte (IO_RTC+1, r); return r; } /* rtcin */
static inline int _Force386_is_tx_ready() { register unsigned8 status; inport_byte( TX_STATUS, status ); if ( Is_tx_ready( status ) ) return 1; else return 0; }
/** * The head is moving up. "Wait" until the head is really up. * Then set status READY to signal we are ready for next hole. */ void control_retract() { uint32_t input; inport_byte(0x7071, input); if ((input & 1) == 1) // is head already UP? { set_status(STATE_READY); } }
uint8_t rtd316_com_get_register(uint32_t addr, uint8_t reg) { register uint8_t val = 0; outport_byte( addr, reg ); /* It appears the no delay is needed between the accesses. */ inport_byte( addr, val ); return val; }
/* * WD interrupt handler */ static void wd8003Enet_interrupt_handler (void *unused) { unsigned int tport; unsigned char status, status2; tport = wd_softc[0].port ; /* * Read status */ inport_byte(tport+ISR, status); outport_byte(tport+IMR, 0x00); /* * Ring overwrite */ if (status & MSK_OVW){ outport_byte(tport+CMDR, MSK_STP + MSK_RD2); /* stop 8390 */ Wait_X_ms(2); outport_byte(tport+RBCR0, 0); /* clear byte count */ outport_byte(tport+RBCR1, 0); inport_byte(tport+ISR, status2); status |= (status2 & (MSK_PTX+MSK_TXE)) ; /* TX status */ outport_byte(tport+TCR, MSK_LOOP); /* loopback mode */ outport_byte(tport+CMDR, MSK_STA + MSK_RD2); /* start */ overrun = 1 ; if ((status & (MSK_PTX+MSK_TXE)) == 0) resend = 1; } /* * Frame received? */ if (status & (MSK_PRX+MSK_RXE)) { outport_byte(tport+ISR, status & (MSK_PRX+MSK_RXE)); wd_softc[0].rxInterrupts++; rtems_event_send (wd_softc[0].rxDaemonTid, INTERRUPT_EVENT); } }
/** * The head should be down or moves to this state. "wait" until * the HEAD_UP signal is false. don't literally wait, just * see if the head is down. If it is, begin retracting and set * RETRACT state. */ void control_punch(int * hole_to_punch) { uint32_t input; inport_byte(0x7071, input); if ((input & 1) == 0){ // is head down? outport_byte(OUT_PUNCH_IRQ, 0b10); // begin retract set_status(STATE_RETRACT); // status "head is moving up" *hole_to_punch += 1; // loop to the next hole newdest = 1; } }
static void sendpacket (struct ifnet *ifp, struct mbuf *m) { struct wd_softc *dp = ifp->if_softc; struct mbuf *n; unsigned int len, tport; uint8_t *shp, txReady; tport = dp->port; /* * Waiting for Transmitter ready */ inport_byte(tport+CMDR, txReady); while(txReady & MSK_TXP) inport_byte(tport+CMDR, txReady); len = 0; shp = dp->base + (SHAPAGE * OUTPAGE); n = m; for (;;){ len += m->m_len; memcpy(shp, (char *)m->m_data, m->m_len); shp += m->m_len ; if ((m = m->m_next) == NULL) break; } m_freem(n); if (len < ET_MINLEN) len = ET_MINLEN; outport_byte(tport+TBCR0, len); outport_byte(tport+TBCR1, (len >> 8) ); outport_byte(tport+TPSR, OUTPAGE); outport_byte(tport+CMDR, MSK_TXP + MSK_RD2); }
static inline int _Force386_read_data() { register unsigned8 ch; #if ( PORTB == 1 ) /* Force example code resets the Channel B Receiver here. * It appears to cause XON's to be lost. */ /* outport_byte( RX_STATUS, 0x10 ); */ #endif inport_byte( RX_BUFFER, ch ); return ch; }
/* * Stop the device */ static void wd_stop (struct wd_softc *sc) { unsigned int tport; unsigned char temp; struct ifnet *ifp = &sc->arpcom.ac_if; ifp->if_flags &= ~IFF_RUNNING; /* * Stop the transmitter */ tport=wd_softc[0].port ; inport_byte(tport+0x04,temp); outport_byte(tport+0x04, temp & 0x7f); outport_byte(tport + CMDR, MSK_STP + MSK_RD2); }
/*-------------------------------------------------------------------------+ | Function: init_rtc | Description: Initialize real-time clock (RTC). | Global Variables: None. | Arguments: None. | Returns: Nothing. +--------------------------------------------------------------------------*/ void init_rtc(void) { uint8_t s; /* initialize brain-dead battery powered clock */ outport_byte(IO_RTC, RTC_STATUSA); outport_byte(IO_RTC+1, 0x26); outport_byte(IO_RTC, RTC_STATUSB); outport_byte(IO_RTC+1, 2); outport_byte(IO_RTC, RTC_DIAG); inport_byte (IO_RTC+1, s); if (s) printk("RTC BIOS diagnostic error %b\n", s); /* FIXME: This was last line's original version. How was it supposed to work? printf("RTC BIOS diagnostic error %b\n", s, RTCDG_BITS); */ } /* init_rtc */
/* * Initialize the ethernet hardware */ static void wd8003Enet_initialize_hardware (struct wd_softc *sc) { int i1, ultra; char cc1, cc2; unsigned char temp; rtems_status_code st; unsigned int tport; unsigned char *hwaddr; tport = sc->port; /* address from board ROM */ inport_byte(tport+0x04, temp); outport_byte(tport+0x04, temp & 0x7f); hwaddr = sc->arpcom.ac_enaddr; for (i1=cc2=0; i1<8; i1++) { inport_byte(tport + ADDROM + i1, cc1); cc2 += cc1; if (i1 < 6) hwaddr[i1] = cc1; } inport_byte(tport+0x04, temp); outport_byte(tport+0x04, temp | 0x80); /* alternate registers */ outport_byte(tport+W83CREG, MSK_RESET); /* reset board, set buffer */ outport_byte(tport+W83CREG, 0); outport_byte(tport+W83CREG, MSK_ENASH + (int)((sc->bpar>>13)&0x3f)); outport_byte(tport+CMDR, MSK_PG0 + MSK_RD2); cc1 = MSK_BMS + MSK_FT10; /* configure 8 or 16 bits */ inport_byte(tport+0x07, temp) ; ultra = ((temp & 0xf0) == 0x20 || (temp & 0xf0) == 0x40); if (ultra) cc1 = MSK_WTS + MSK_BMS + MSK_FT10; outport_byte(tport+DCR, cc1); outport_byte(tport+RBCR0, 0); outport_byte(tport+RBCR1, 0); outport_byte(tport+RCR, MSK_MON); /* disable the rxer */ outport_byte(tport+TCR, 0); /* normal operation */ outport_byte(tport+PSTOP, OUTPAGE); /* init PSTOP */ outport_byte(tport+PSTART, 0); /* init PSTART */ outport_byte(tport+BNRY, -1); /* init BNRY */ outport_byte(tport+ISR, -1); /* clear IR's */ outport_byte(tport+IMR, 0x15); /* enable interrupt */ outport_byte(tport+CMDR, MSK_PG1 + MSK_RD2); for (i1=0; i1<6; i1++) /* initial physical addr */ outport_byte(tport+PAR+i1, hwaddr[i1]); for (i1=0; i1<MARsize; i1++) /* clear multicast */ outport_byte(tport+MAR+i1, 0); outport_byte(tport+CURR, 0); /* init current packet */ outport_byte(tport+CMDR, MSK_PG0 + MSK_RD2); outport_byte(tport+CMDR, MSK_STA + MSK_RD2); /* put 8390 on line */ outport_byte(tport+RCR, MSK_AB); /* MSK_AB accept broadcast */ if (ultra) { inport_byte(tport+0x0c, temp); outport_byte(tport+0x0c, temp | 0x80); outport_byte(tport+0x05, 0x80); outport_byte(tport+0x06, 0x01); } /* * Set up interrupts */ sc->irqInfo.hdl = wd8003Enet_interrupt_handler; sc->irqInfo.on = nopOn; sc->irqInfo.off = nopOn; sc->irqInfo.isOn = wdIsOn; st = BSP_install_rtems_irq_handler (&sc->irqInfo); if (!st) rtems_panic ("Can't attach WD interrupt handler for irq %d\n", sc->irqInfo.name); }
/*=========================================================================*\ | Function: | \*-------------------------------------------------------------------------*/ void pc386_ide_initialize ( /*-------------------------------------------------------------------------*\ | Purpose: | | initialize IDE access | +---------------------------------------------------------------------------+ | Input Parameters: | \*-------------------------------------------------------------------------*/ int minor /* controller minor number */ ) /*-------------------------------------------------------------------------*\ | Return Value: | | <none> | \*=========================================================================*/ { uint32_t port = IDE_Controller_Table[minor].port1; uint8_t dev = 0; if (pc386_ide_show) printk("IDE%d: port base: %04x\n", minor, port); outport_byte(port+IDE_REGISTER_DEVICE_HEAD, (dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS) | 0xE0); wait(10000); outport_byte(port+IDE_REGISTER_DEVICE_CONTROL, IDE_REGISTER_DEVICE_CONTROL_SRST | IDE_REGISTER_DEVICE_CONTROL_nIEN); wait(10000); outport_byte(port+IDE_REGISTER_DEVICE_CONTROL, IDE_REGISTER_DEVICE_CONTROL_nIEN); wait(10000); for (dev = 0; dev < 2; dev++) { uint16_t capabilities = 0; uint32_t byte; uint8_t status; uint8_t error; uint8_t cyllsb; uint8_t cylmsb; const char* label = dev ? " slave" : "master"; int max_multiple_sectors = 0; int cur_multiple_sectors = 0; uint32_t cylinders = 0; uint32_t heads = 0; uint32_t sectors = 0; uint32_t lba_sectors = 0; char model_number[41]; char* p = &model_number[0]; bool data_ready; memset(model_number, 0, sizeof(model_number)); outport_byte(port+IDE_REGISTER_DEVICE_HEAD, (dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS) | 0xE0); /* outport_byte(port+IDE_REGISTER_SECTOR_NUMBER, (dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS) | IDE_REGISTER_LBA3_L); */ outport_byte(port+IDE_REGISTER_COMMAND, 0x00); if (!pc386_ide_status_busy (port, PC386_IDE_PROBE_TIMEOUT, &status, pc386_ide_prestart_sleep)) continue; inport_byte(port+IDE_REGISTER_STATUS, status); inport_byte(port+IDE_REGISTER_ERROR, error); inport_byte(port+IDE_REGISTER_CYLINDER_LOW, cyllsb); inport_byte(port+IDE_REGISTER_CYLINDER_HIGH, cylmsb); if (pc386_ide_show) { printk("IDE%d:%s: status=%02x\n", minor, label, status); printk("IDE%d:%s: error=%02x\n", minor, label, error); printk("IDE%d:%s: cylinder-low=%02x\n", minor, label, cyllsb); printk("IDE%d:%s: cylinder-high=%02x\n", minor, label, cylmsb); } outport_byte(port+IDE_REGISTER_COMMAND, 0xec); if (!pc386_ide_status_busy (port, PC386_IDE_PRESTART_TIMEOUT, &status, pc386_ide_prestart_sleep)) { if (pc386_ide_show) printk("IDE%d:%s: device busy: %02x\n", minor, label, status); continue; } data_ready = pc386_ide_status_data_ready (port, 250, &status, pc386_ide_prestart_sleep); if (status & IDE_REGISTER_STATUS_ERR) { inport_byte(port+IDE_REGISTER_ERROR, error); if (error != 4) { if (pc386_ide_show) printk("IDE%d:%s: error=%04x\n", minor, label, error); continue; } /* * The device is an ATAPI device. */ outport_byte(port+IDE_REGISTER_COMMAND, 0xa1); data_ready = pc386_ide_status_data_ready (port, 250, &status, pc386_ide_prestart_sleep); } if (!data_ready) continue; byte = 0; while (byte < 512) { uint16_t word; if (pc386_ide_show && ((byte % 16) == 0)) printk("\n %04x : ", byte); inport_word(port+IDE_REGISTER_DATA, word); if (pc386_ide_show) printk ("%04x ", word); if (byte == 2) cylinders = word; if (byte == 6) heads = word; if (byte == 12) sectors = word; if (byte >= 54 && byte < (54 + 40)) { *p = word >> 8; p++; *p = word; p++; } if (byte == (47 * 2)) max_multiple_sectors = word & 0xff; if (byte == (49 * 2)) capabilities = word; if (byte == (59 * 2)) { if (word & (1 << 8)) cur_multiple_sectors = word & 0xff; } if (byte == (60 * 2)) lba_sectors = word; if (byte == (61 * 2)) lba_sectors |= word << 16; byte += 2; } if (pc386_ide_show) printk("\nbytes read = %d\n", byte); if (p != &model_number[0]) { uint32_t size; uint32_t left; uint32_t right; char units; if (capabilities & (1 << 9)) size = lba_sectors; else size = cylinders * heads * sectors; size /= 2; if (size > (1024 * 1024)) { size = (size * 10) / (1000 * 1000); units = 'G'; } else if (size > 1024) { size = (size * 10) / 1000; units = 'M'; } else { size = size * 10; units = 'K'; } left = size / 10; right = size % 10; p--; while (*p == ' ') { *p = '\0'; p--; } printk("IDE%d:%s:%s, %u.%u%c (%u/%u/%u), max blk size:%d\n", minor, label, model_number, left, right, units, heads, cylinders, sectors, max_multiple_sectors * 512); } #if IDE_CLEAR_MULTI_SECTOR_COUNT if (max_multiple_sectors) { outport_byte(port+IDE_REGISTER_SECTOR_COUNT, 0); outport_byte(port+IDE_REGISTER_COMMAND, 0xc6); if (!pc386_ide_status_busy (port, PC386_IDE_PRESTART_TIMEOUT, &status, pc386_ide_prestart_sleep)) { if (pc386_ide_show) printk("IDE%d:%s: device busy: %02x\n", minor, label, status); continue; } inport_byte(port+IDE_REGISTER_STATUS, status); if (status & IDE_REGISTER_STATUS_ERR) { inport_byte(port+IDE_REGISTER_ERROR, error); if (error & IDE_REGISTER_ERROR_ABRT) printk("IDE%d:%s: disable multiple failed\n", minor, label); else printk("IDE%d:%s: unknown error on disable multiple: %02x\n", minor, label, error); } } #endif outport_byte(port+IDE_REGISTER_DEVICE_CONTROL, IDE_REGISTER_DEVICE_CONTROL_nIEN); wait(10000); }
static void wd_rxDaemon (void *arg) { unsigned int tport; struct ether_header *eh; struct wd_softc *dp = (struct wd_softc *)&wd_softc[0]; struct ifnet *ifp = &dp->arpcom.ac_if; struct mbuf *m; unsigned int i2; unsigned int len; volatile unsigned char start, next, current; unsigned char *shp, *temp; unsigned short *real_short_ptr; rtems_event_set events; tport = wd_softc[0].port ; for (;;){ rtems_bsdnet_event_receive (INTERRUPT_EVENT, RTEMS_WAIT|RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &events); for (;;){ inport_byte(tport+BNRY, start); outport_byte(tport+CMDR, MSK_PG1 + MSK_RD2); inport_byte(tport+CURR, current); outport_byte(tport+CMDR, MSK_PG0 + MSK_RD2); start += 1; if (start >= OUTPAGE){ start = 0; } if (current == start) break; /* real_short_ptr avoids cast on lvalue which gcc no longer allows */ shp = dp->base + 1 + (SHAPAGE * start); next = *shp++; real_short_ptr = (unsigned short *)shp; len = *(real_short_ptr)++ - 4; if (next >= OUTPAGE){ next = 0; } MGETHDR (m, M_WAIT, MT_DATA); MCLGET (m, M_WAIT); m->m_pkthdr.rcvif = ifp; temp = (unsigned char *) m->m_data; m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header); if ((i2 = (OUTPAGE - start) * SHAPAGE - 4) < len){ memcpy(temp, shp, i2); len -= i2; temp += i2; shp = dp->base; } memcpy(temp, shp, len); eh = mtod (m, struct ether_header *); m->m_data += sizeof(struct ether_header); ether_input (ifp, eh, m); outport_byte(tport+BNRY, next-1); } /* * Ring overwrite */ if (overrun){ outport_byte(tport+ISR, MSK_OVW); /* reset IR */ outport_byte(tport+TCR, 0); /* out of loopback */ if (resend == 1) outport_byte(tport+CMDR, MSK_TXP + MSK_RD2); /* resend */ resend = 0; overrun = 0; } outport_byte(tport+IMR, 0x15); /* re-enable IT rx */ } }
/*-------------------------------------------------------------------------+ | Function: _IBMPC_scankey | Description: This function can be called during a poll for input, or by | an ISR. Basically any time you want to process a keypress. | Global Variables: key_map, shift_map. | Arguments: outChar - character read in case of a valid reading, | otherwise unchanged. | Returns: TRUE in case a valid character has been read, | FALSE otherwise. +--------------------------------------------------------------------------*/ static bool _IBMPC_scankey(char *outChar) { unsigned char inChar; static int alt_pressed = 0; static int ctrl_pressed = 0; static int shift_pressed = 0; static int caps_pressed = 0; static int extended = 0; *outChar = '\0'; /* default value if we return false */ /* Read keyboard controller, toggle enable */ inport_byte(KBD_CTL, inChar); outport_byte(KBD_CTL, inChar & ~0x80); outport_byte(KBD_CTL, inChar | 0x80); outport_byte(KBD_CTL, inChar & ~0x80); /* See if it has data */ inport_byte(KBD_STATUS, inChar); if ((inChar & 0x01) == 0) return false; /* Read the data. Handle nonsense with shift, control, etc. */ inport_byte(KBD_DATA, inChar); if (extended) extended--; switch (inChar) { case 0xe0: extended = 2; return false; break; case 0x38: alt_pressed = 1; return false; break; case 0xb8: alt_pressed = 0; return false; break; case 0x1d: ctrl_pressed = 1; return false; break; case 0x9d: ctrl_pressed = 0; return false; break; case 0x2a: if (extended) return false; case 0x36: shift_pressed = 1; return false; break; case 0xaa: if (extended) return false; case 0xb6: shift_pressed = 0; return false; break; case 0x3a: caps_pressed = 1; return false; break; case 0xba: caps_pressed = 0; return false; break; case 0x53: if (ctrl_pressed && alt_pressed) bsp_reset(); /* ctrl+alt+del -> reboot */ break; /* * Ignore unrecognized keys--usually arrow and such */ default: if ((inChar & 0x80) || (inChar > 0x39)) /* High-bit on means key is being released, not pressed */ return false; break; } /* switch */ /* Strip high bit, look up in our map */ inChar &= 0x7f; if (ctrl_pressed) { *outChar = key_map[inChar]; *outChar &= 037; } else { *outChar = shift_pressed ? shift_map[inChar] : key_map[inChar]; if (caps_pressed) { if (*outChar >= 'A' && *outChar <= 'Z') *outChar += 'a' - 'A'; else if (*outChar >= 'a' && *outChar <= 'z') *outChar -= 'a' - 'A'; } } return true; } /* _IBMPC_scankey */