static int timer_callback(registers_t* regs) { tick++; DebugPrint("tick: %d\n", tick); irq_ack(TIMER_IRQ); return 1; }
void uart_init(void) { uint32_t mask; uint8_t value; rx_produce = 0; rx_consume = 0; irq_ack(IRQ_UART); /* enable UART interrupts */ writeb(LM32_UART_IER_RBRI, &uart->ier); mask = irq_getmask(); mask |= IRQ_UART; irq_setmask(mask); /* Line control 8 bit, 1 stop, no parity */ writeb(LM32_UART_LCR_8BIT, &uart->lcr); /* Modem control, DTR = 1, RTS = 1 */ writeb(LM32_UART_MCR_DTR | LM32_UART_MCR_RTS, &uart->mcr); /* Set baud rate */ value = (CPU_FREQUENCY / UART_BAUD_RATE) & 0xff; writeb(value, &uart->divl); value = (CPU_FREQUENCY / UART_BAUD_RATE) >> 8; writeb(value, &uart->divh); }
void isr(void) { unsigned int irqs; irqs = irq_pending() & irq_getmask(); if(irqs & IRQ_UART) uart_isr(); if(irqs & IRQ_TIMER0) time_isr(); if(irqs & IRQ_AC97CRREQUEST) snd_isr_crrequest(); if(irqs & IRQ_AC97CRREPLY) snd_isr_crreply(); if(irqs & IRQ_AC97DMAR) snd_isr_dmar(); if(irqs & IRQ_AC97DMAW) snd_isr_dmaw(); if(irqs & IRQ_TMU) tmu_isr(); if(irqs & IRQ_PFPU) pfpu_isr(); irq_ack(irqs); }
void c5471_init_irq(void) { /* Disable all interrupts. */ REG32(MASK_IT_REG) = 0x0000ffff; /* Clear any pending interrupts */ irq_ack(0); fiq_ack(0); REG32(IT_REG) = 0x00000000; /* Override hardware defaults */ REG32(ILR_IRQ2_REG) = EdgeSensitive | Priority; REG32(ILR_IRQ4_REG) = EdgeSensitive | Priority; REG32(ILR_IRQ6_REG) = Priority; REG32(ILR_IRQ15_REG) = EdgeSensitive | Priority; /* Finally, be a good citizen and do what it takes to insure * the user gets accurate info if they type "cat /proc/ioports" */ // request_region(INT_FIRST_IO, INT_IO_RANGE, "interrupt controller"); OZH }
void snd_isr_dmaw() { asm volatile( /* Invalidate Level-1 data cache */ "wcsr DCC, r0\n" "nop\n" ); if(record_level == 0) { printf("SND: stray DMAW irq\n"); return; } /* NB. the callback can give us buffers by calling snd_record_refill() */ record_callback(record_queue[record_consume], record_user); record_consume = (record_consume + 1) & RECORD_BUFQ_MASK; record_level--; irq_ack(IRQ_AC97DMAW); if(record_level > 0) record_start(record_queue[record_consume]); else record_overrun = 1; }
static int rtl_irq_handler(struct regs *r) { uint16_t status = inports(rtl_iobase + RTL_PORT_ISR); if (!status) { return 0; } outports(rtl_iobase + RTL_PORT_ISR, status); irq_ack(rtl_irq); if (status & 0x01 || status & 0x02) { /* Receive */ while((inportb(rtl_iobase + RTL_PORT_CMD) & 0x01) == 0) { int offset = cur_rx % 0x2000; #if 0 uint16_t buf_addr = inports(rtl_iobase + RTL_PORT_RXADDR); uint16_t buf_ptr = inports(rtl_iobase + RTL_PORT_RXPTR); uint8_t cmd = inportb(rtl_iobase + RTL_PORT_CMD); #endif uint32_t * buf_start = (uint32_t *)((uintptr_t)rtl_rx_buffer + offset); uint32_t rx_status = buf_start[0]; int rx_size = rx_status >> 16; if (rx_status & (0x0020 | 0x0010 | 0x0004 | 0x0002)) { debug_print(WARNING, "rx error :("); } else { uint8_t * buf_8 = (uint8_t *)&(buf_start[1]); last_packet = malloc(rx_size); uintptr_t packet_end = (uintptr_t)buf_8 + rx_size; if (packet_end > (uintptr_t)rtl_rx_buffer + 0x2000) { size_t s = ((uintptr_t)rtl_rx_buffer + 0x2000) - (uintptr_t)buf_8; memcpy(last_packet, buf_8, s); memcpy((void *)((uintptr_t)last_packet + s), rtl_rx_buffer, rx_size - s); } else { memcpy(last_packet, buf_8, rx_size); } rtl_enqueue(last_packet); } cur_rx = (cur_rx + rx_size + 4 + 3) & ~3; outports(rtl_iobase + RTL_PORT_RXPTR, cur_rx - 16); } wakeup_queue(rx_wait); } if (status & 0x08 || status & 0x04) { unsigned int i = inportl(rtl_iobase + RTL_PORT_TXSTAT + 4 * dirty_tx); (void)i; dirty_tx++; if (dirty_tx == 5) dirty_tx = 0; } return 1; }
/* * Keyboard interrupt callback */ static int keyboard_handler(struct regs *r) { unsigned char scancode; keyboard_wait(); scancode = inportb(KEY_DEVICE); irq_ack(KEY_IRQ); write_fs(keyboard_pipe, 0, 1, (uint8_t []){scancode}); return 1; }
char readchar() { char c; while(!(irq_pending() & IRQ_UARTRX)); irq_ack(IRQ_UARTRX); c = CSR_UART_RXTX; return c; }
void uart_isr(void) { while (readb(&uart->lsr) & LM32_UART_LSR_DR) { rx_buf[rx_produce] = readb(&uart->rxtx); rx_produce = (rx_produce + 1) & UART_RINGBUFFER_MASK_RX; } irq_ack(IRQ_UART); }
void kb_intr(void* unused) { if(!(inb(PS2_CTRL) & 0x01)) return; uint8_t vkscan = inb(PS2_DATA); switch(vkscan) { case PS2_ACK: case PS2_RESEND: return; case 0xE0: case 0xE1: kb.e0++; return; } irq_ack(1); uint16_t vkey = KEY_RESERVED; if(kb.e0) vkey = kb.vkeymap[0x100 | (vkscan & 0x7F)]; else vkey = kb.vkeymap[vkscan & 0x7F]; kb.e0 = 0; if(vkey == KEY_RESERVED) return; switch(vkey) { case KEY_CAPSLOCK: kb.capslock != kb.capslock; kb_setled(); break; case KEY_NUMLOCK: kb.numlock != kb.numlock; kb_setled(); break; case KEY_SCROLLLOCK: kb.scrolllock != kb.scrolllock; kb_setled(); } keyboard_t k; k.vkey = vkey; k.down = !!!(vkscan & 0x80); sys_events_raise_EV_KEY(kdid, k.vkey, k.down); __fifo_send(PATH_KBDEV, &k, sizeof(keyboard_t)); PS2_WAIT; }
void slowout_isr() { irq_ack(IRQ_TIMER1); consume = (consume + 1) & OPQ_MASK; level--; if(level > 0) slowout_start(&queue[consume]); else cts = 1; }
void snd_record_stop() { unsigned int oldmask; oldmask = irq_getmask(); irq_setmask(oldmask & (~IRQ_AC97DMAW)); CSR_AC97_UCTL = 0; /* this also acks any pending IRQ in the AC97 core */ irq_ack(IRQ_AC97DMAW); irq_setmask(oldmask); }
void snd_record_stop() { unsigned int oldmask; oldmask = irq_getmask(); irq_setmask(0); CSR_AC97_UCTL = 0; record_overrun = 0; irq_ack(IRQ_AC97DMAW); irq_setmask(oldmask); }
void snd_play_stop() { unsigned int oldmask; oldmask = irq_getmask(); irq_setmask(0); CSR_AC97_DCTL = 0; play_underrun = 0; irq_ack(IRQ_AC97DMAR); irq_setmask(oldmask); }
void serial_handler_a(registers_t *regs) { int8_t serial = serial_recv(SERIAL_PORT_A); irq_ack(SERIAL_IRQ); if (serial == 13) { serial = '\n'; } printf("%c", serial); serial_send(SERIAL_PORT_B, serial); }
void irq_handler(regs_t *r) { CLI; int i = r->int_no - 32; if (i >= 0 && i <= 15) { irq_handler_t handler = irq_routines[i]; if (handler != NULL) { handler(r); } else { irq_ack(i); } } STI; }
void mouse_handler(struct regs *r) { uint8_t status = inportb(MOUSE_STATUS); while (status & MOUSE_BBIT) { int8_t mouse_in = inportb(MOUSE_PORT); if (status & MOUSE_F_BIT) { switch (mouse_cycle) { case 0: mouse_byte[0] = mouse_in; if (!(mouse_in & MOUSE_V_BIT)) return; ++mouse_cycle; break; case 1: mouse_byte[1] = mouse_in; ++mouse_cycle; break; case 2: mouse_byte[2] = mouse_in; /* We now have a full mouse packet ready to use */ if (mouse_byte[0] & 0x80 || mouse_byte[0] & 0x40) { /* x/y overflow? bad packet! */ break; } mouse_device_packet_t packet; packet.magic = MOUSE_MAGIC; packet.x_difference = mouse_byte[1]; packet.y_difference = mouse_byte[2]; packet.buttons = 0; if (mouse_byte[0] & 0x01) { packet.buttons |= LEFT_CLICK; } if (mouse_byte[0] & 0x02) { packet.buttons |= RIGHT_CLICK; } if (mouse_byte[0] & 0x04) { packet.buttons |= MIDDLE_CLICK; } mouse_cycle = 0; mouse_device_packet_t bitbucket; while (pipe_size(mouse_pipe) > (DISCARD_POINT * sizeof(packet))) { read_fs(mouse_pipe, 0, sizeof(packet), (uint8_t *)&bitbucket); } write_fs(mouse_pipe, 0, sizeof(packet), (uint8_t *)&packet); break; } } status = inportb(MOUSE_STATUS); } irq_ack(MOUSE_IRQ); }
static int serial_handler_ac(struct regs *r) { char serial; int port = 0; if (inportb(SERIAL_PORT_A+1) & 0x01) { port = SERIAL_PORT_A; } else { port = SERIAL_PORT_C; } serial = serial_recv(port); irq_ack(SERIAL_IRQ_AC); uint8_t buf[] = {convert(serial), 0}; write_fs(*pipe_for_port(port), 0, 1, buf); return 1; }
static void pcnet_irq(void* context) { struct pcnet* dev = (struct pcnet*) irq_get_data(pcnet_irqno); if(unlikely(!dev)) { kprintf(ERROR "pcnet: invalid irq#%d\n", pcnet_irqno); return; } uint32_t x = r_csr32(dev, 0) | 0x0400; w_csr32(dev, 0, x); irq_ack(dev->irq); while(d_owns((uint8_t*) dev->rxdes, dev->rxid)) ethif_input(dev->netif); }
void irq_handler(struct regs *r) { IRQ_OFF; void (*handler)(struct regs *r); if (r->int_no > 47 || r->int_no < 32) { handler = NULL; } else { handler = irq_routines[r->int_no - 32]; } if (handler) { handler(r); } else { irq_ack(r->int_no - 32); } IRQ_RES; }
static int serial_handler_bd(struct regs *r) { char serial; int port = 0; debug_print(NOTICE, "Received something on secondary port"); if (inportb(SERIAL_PORT_B+1) & 0x01) { port = SERIAL_PORT_B; } else { port = SERIAL_PORT_D; } serial = serial_recv(port); irq_ack(SERIAL_IRQ_BD); uint8_t buf[] = {convert(serial), 0}; write_fs(*pipe_for_port(port), 0, 1, buf); return 1; }
void keyboard_callback(registers_t *regs) { while(inb(PS2_COMMAND_PORT) & 2) {} uint8_t scan_code = inb(PS2_DATA_PORT); // TODO: send back RESEND if something was wrong. irq_ack(IRQ1); printk("scan_code found: %x\n", scan_code); // open '/dev/keyboard', write scan_code to it. // TODO: make this understand paths better. fs_node_t * keyboard = devfs_keyboard; if (keyboard) { printk("calling write_fs with %x %c\n", scan_code, scan_code); write_fs(keyboard, 0, 4, scan_code); } else { printk("ERROR: can't write to NULL /dev/keyboard char device.\n"); } }
void snd_init() { unsigned int codec_id; unsigned int mask; if(!(CSR_CAPABILITIES & CAP_AC97)) { printf("SND: not supported by SoC, giving up.\n"); return; } snd_cr_request = 0; snd_cr_reply = 0; /* Reset AC'97 controller */ CSR_AC97_CRCTL = 0; CSR_AC97_DCTL = 0; CSR_AC97_UCTL = 0; irq_ack(IRQ_AC97CRREQUEST|IRQ_AC97CRREPLY|IRQ_AC97DMAR|IRQ_AC97DMAW); mask = irq_getmask(); mask |= IRQ_AC97CRREQUEST|IRQ_AC97CRREPLY|IRQ_AC97DMAR|IRQ_AC97DMAW; irq_setmask(mask); codec_id = snd_ac97_read(0x00); if(codec_id == 0x0d50) printf("SND: found LM4550 AC'97 codec\n"); else if(codec_id == 0x6150) printf("SND: found WM9707 AC'97 codec\n"); else printf("SND: warning, unknown codec found (ID:%04x)\n", codec_id); /* Unmute and set volumes */ /* TODO: API for this */ snd_ac97_write(0x02, 0x0000); /* master volume */ snd_ac97_write(0x04, 0x0f0f); /* headphones volume */ snd_ac97_write(0x18, 0x0000); /* PCM out volume */ snd_ac97_write(0x1c, 0x0f0f); /* record gain */ snd_ac97_write(0x0e, 0x0000); /* mic volume: max */ snd_ac97_write(0x10, 0x0000); /* line in volume: max */ snd_ac97_write(0x1a, 0x0505); /* record select: stero mix */ snd_play_empty(); snd_record_empty(); printf("SND: initialization complete\n"); }
void snd_isr_dmar() { /* NB. the callback can give us buffers by calling snd_play_refill() */ play_callback(play_queue[play_consume], play_user); play_consume = (play_consume + 1) & PLAY_BUFQ_MASK; play_level--; irq_ack(IRQ_AC97DMAR); if(play_level > 0) play_start(play_queue[play_consume]); else { printf("SND: playing underrun\n"); play_underrun = 1; } }
void pfpu_init() { unsigned int mask; /* Reset PFPU */ CSR_PFPU_CTL = 0; irq_ack(IRQ_PFPU); produce = 0; consume = 0; level = 0; cts = 1; mask = irq_getmask(); mask |= IRQ_PFPU; irq_setmask(mask); printf("FPU: programmable floating point unit initialized\n"); }
void tmu_init() { unsigned int mask; frequency = get_board_desc()->clk_frequency; produce = 0; consume = 0; level = 0; cts = 1; CSR_TMU_CTL = 0; irq_ack(IRQ_TMU); mask = irq_getmask(); mask |= IRQ_TMU; irq_setmask(mask); printf("TMU: texture mapping unit initialized\n"); }
void slowout_init() { unsigned int mask; produce = 0; consume = 0; level = 0; cts = 1; /* Reset timer */ CSR_TIMER1_CONTROL = 0; irq_ack(IRQ_TIMER1); mask = irq_getmask(); mask |= IRQ_TIMER1; irq_setmask(mask); printf("SLO: slow outputs initialized\n"); }
void uart_isr(void) { unsigned int stat = CSR_UART_STAT; if(stat & UART_STAT_RX_EVT) { rx_buf[rx_produce] = CSR_UART_RXTX; rx_produce = (rx_produce + 1) & UART_RINGBUFFER_MASK_RX; } if(stat & UART_STAT_TX_EVT) { if(tx_produce != tx_consume) { CSR_UART_RXTX = tx_buf[tx_consume]; tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX; } else tx_cts = 1; } CSR_UART_STAT = stat; irq_ack(IRQ_UART); }
asmlinkage int IRQ_interrupt(int irq, struct pt_regs * regs) { register unsigned long flags; register unsigned long saved_count; register unsigned char spr = atmel_irq_priority; atmel_irq_priority = ((unsigned char)irq) | atmel_irq_prtable[irq]; saved_count = intr_count; intr_count = saved_count + 1; save_flags(flags); sti(); do_IRQ(irq, regs); restore_flags(flags); intr_count = saved_count; atmel_irq_priority = spr; irq_ack(spr); return 0; }
static void wss_irq() { /* Make sure its not a spurious IRQ */ if (!irq_check(wss.irq_handle)) return; wss.irqcount++; /* Clear IRQ status */ outportb(WSS_STATUS, 0); /* Write transfer count again */ __wss_outreg(WSSR_COUNT_LOW, wss.samples & 0xff); __wss_outreg(WSSR_COUNT_HIGH, wss.samples >> 8); irq_ack(wss.irq_handle); enable(); if (wss.timer_callback) wss.timer_callback(); }