diff options
author | Freya Murphy <freya@freyacat.org> | 2025-04-08 10:49:18 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2025-04-08 10:49:18 -0400 |
commit | c8a1e0531d7ccdce5f76aec8a5b6147c686d3403 (patch) | |
tree | 2a68ab7da901a96fea975ca2ec02a9c77137686b /kernel/old/drivers | |
parent | tty => term (diff) | |
download | comus-c8a1e0531d7ccdce5f76aec8a5b6147c686d3403.tar.gz comus-c8a1e0531d7ccdce5f76aec8a5b6147c686d3403.tar.bz2 comus-c8a1e0531d7ccdce5f76aec8a5b6147c686d3403.zip |
fix old checkout
Diffstat (limited to 'kernel/old/drivers')
-rw-r--r-- | kernel/old/drivers/clock.c | 152 | ||||
-rw-r--r-- | kernel/old/drivers/serial.c | 629 |
2 files changed, 0 insertions, 781 deletions
diff --git a/kernel/old/drivers/clock.c b/kernel/old/drivers/clock.c deleted file mode 100644 index 9f3d4be..0000000 --- a/kernel/old/drivers/clock.c +++ /dev/null @@ -1,152 +0,0 @@ -#define KERNEL_SRC - -#include <common.h> - -#include <clock.h> -#include <procs.h> - -#include <x86/arch.h> -#include <x86/pic.h> -#include <x86/pit.h> - -/* -** PRIVATE DEFINITIONS -*/ - -/* -** PRIVATE DATA TYPES -*/ - -/* -** PRIVATE GLOBAL VARIABLES -*/ - -// pinwheel control variables -static uint32_t pinwheel; // pinwheel counter -static uint32_t pindex; // index into pinwheel string - -/* -** PUBLIC GLOBAL VARIABLES -*/ - -// current system time -uint32_t system_time; - -/* -** PRIVATE FUNCTIONS -*/ - -/** -** Name: clk_isr -** -** The ISR for the clock -** -** @param vector Vector number for the clock interrupt -** @param code Error code (0 for this interrupt) -*/ -static void clk_isr(int vector, int code) -{ - // spin the pinwheel - - ++pinwheel; - if (pinwheel == (CLOCK_FREQ / 10)) { - pinwheel = 0; - ++pindex; - cio_putchar_at(0, 0, "|/-\\"[pindex & 3]); - } - -#if defined(SYSTEM_STATUS) - // Periodically, dump the queue lengths and the SIO status (along - // with the SIO buffers, if non-empty). - // - // Define the symbol SYSTEM_STATUS with a value equal to the desired - // reporting frequency, in seconds. - - if ((system_time % SEC_TO_TICKS(SYSTEM_STATUS)) == 0) { - cio_printf_at(1, 0, " queues: R[%u] W[%u] S[%u] Z[%u] I[%u] ", - pcb_queue_length(ready), pcb_queue_length(waiting), - pcb_queue_length(sleeping), pcb_queue_length(zombie), - pcb_queue_length(sioread)); - } -#endif - - // time marches on! - ++system_time; - - // wake up any sleeping processes whose time has come - // - // we give them preference over the current process when - // it is scheduled again - - do { - // if there isn't anyone in the sleep queue, we're done - if (pcb_queue_empty(sleeping)) { - break; - } - - // peek at the first member of the queue - pcb_t *tmp = pcb_queue_peek(sleeping); - assert(tmp != NULL); - - // the sleep queue is sorted in ascending order by wakeup - // time, so we know that the retrieved PCB's wakeup time is - // the earliest of any process on the sleep queue; if that - // time hasn't arrived yet, there's nobody left to awaken - - if (tmp->wakeup > system_time) { - break; - } - - // OK, we need to wake this process up - assert(pcb_queue_remove(sleeping, &tmp) == SUCCESS); - schedule(tmp); - } while (1); - - // next, we decrement the current process' remaining time - current->ticks -= 1; - - // has it expired? - if (current->ticks < 1) { - // yes! reschedule it - schedule(current); - current = NULL; - // and pick a new process - dispatch(); - } - - // tell the PIC we're done - outb(PIC1_CMD, PIC_EOI); -} - -/* -** PUBLIC FUNCTIONS -*/ - -/** -** Name: clk_init -** -** Initializes the clock module -** -*/ -void clk_init(void) -{ -#if TRACING_INIT - cio_puts(" Clock"); -#endif - - // start the pinwheel - pinwheel = (CLOCK_FREQ / 10) - 1; - pindex = 0; - - // return to the dawn of time - system_time = 0; - - // configure the clock - uint32_t divisor = PIT_FREQ / CLOCK_FREQ; - outb(PIT_CONTROL_PORT, PIT_0_LOAD | PIT_0_SQUARE); - outb(PIT_0_PORT, divisor & 0xff); // LSB of divisor - outb(PIT_0_PORT, (divisor >> 8) & 0xff); // MSB of divisor - - // register the second-stage ISR - install_isr(VEC_TIMER, clk_isr); -} diff --git a/kernel/old/drivers/serial.c b/kernel/old/drivers/serial.c deleted file mode 100644 index d6572e5..0000000 --- a/kernel/old/drivers/serial.c +++ /dev/null @@ -1,629 +0,0 @@ -#define KERNEL_SRC - -// this should do all includes required for this OS -#include <compat.h> - -// all other framework includes are next -#include <x86/uart.h> -#include <x86/arch.h> -#include <x86/pic.h> - -#include <sio.h> -#include <lib.h> - -/* -** PRIVATE DEFINITIONS -*/ - -#define BUF_SIZE 2048 - -/* -** PRIVATE GLOBALS -*/ - -// input character buffer -static char inbuffer[BUF_SIZE]; -static char *inlast; -static char *innext; -static uint32_t incount; - -// output character buffer -static char outbuffer[BUF_SIZE]; -static char *outlast; -static char *outnext; -static uint32_t outcount; - -// output control flag -static int sending; - -// interrupt register status -static uint8_t ier; - -/* -** PUBLIC GLOBAL VARIABLES -*/ - -// queue for read-blocked processes -#ifdef QNAME -extern QTYPE QNAME; -#endif - -/* -** PRIVATE FUNCTIONS -*/ - -/** -** sio_isr(vector,ecode) -** -** Interrupt handler for the SIO module. Handles all pending -** events (as described by the SIO controller). -** -** @param vector The interrupt vector number for this interrupt -** @param ecode The error code associated with this interrupt -*/ -static void sio_isr(int vector, int ecode) -{ - int ch; - -#if TRACING_SIO_ISR - cio_puts("SIO: int:"); -#endif - // - // Must process all pending events; loop until the IRR - // says there's nothing else to do. - // - - for (;;) { - // get the "pending event" indicator - int iir = inb(UA4_IIR) & UA4_IIR_INT_PRI_MASK; - - // process this event - switch (iir) { - case UA4_IIR_LINE_STATUS: - // shouldn't happen, but just in case.... - cio_printf("** SIO int, LSR = %02x\n", inb(UA4_LSR)); - break; - - case UA4_IIR_RX: -#if TRACING_SIO_ISR - cio_puts(" RX"); -#endif - // get the character - ch = inb(UA4_RXD); - if (ch == '\r') { // map CR to LF - ch = '\n'; - } -#if TRACING_SIO_ISR - cio_printf(" ch %02x", ch); -#endif - -#ifdef QNAME - // - // If there is a waiting process, this must be - // the first input character; give it to that - // process and awaken the process. - // - - if (!QEMPTY(QNAME)) { - PCBTYPE *pcb; - - QDEQUE(QNAME, pcb); - // make sure we got a non-NULL result - assert(pcb); - - // return char via arg #2 and count in EAX - char *buf = (char *)ARG(pcb, 2); - *buf = ch & 0xff; - RET(pcb) = 1; - SCHED(pcb); - - } else { -#endif /* QNAME */ - - // - // Nobody waiting - add to the input buffer - // if there is room, otherwise just ignore it. - // - - if (incount < BUF_SIZE) { - *inlast++ = ch; - ++incount; - } - -#ifdef QNAME - } -#endif /* QNAME */ - break; - - case UA5_IIR_RX_FIFO: - // shouldn't happen, but just in case.... - ch = inb(UA4_RXD); - cio_printf("** SIO FIFO timeout, RXD = %02x\n", ch); - break; - - case UA4_IIR_TX: -#if TRACING_SIO_ISR - cio_puts(" TX"); -#endif - // if there is another character, send it - if (sending && outcount > 0) { -#if TRACING_SIO_ISR - cio_printf(" ch %02x", *outnext); -#endif - outb(UA4_TXD, *outnext); - ++outnext; - // wrap around if necessary - if (outnext >= (outbuffer + BUF_SIZE)) { - outnext = outbuffer; - } - --outcount; -#if TRACING_SIO_ISR - cio_printf(" (outcount %d)", outcount); -#endif - } else { -#if TRACING_SIO_ISR - cio_puts(" EOS"); -#endif - // no more data - reset the output vars - outcount = 0; - outlast = outnext = outbuffer; - sending = 0; - // disable TX interrupts - sio_disable(SIO_TX); - } - break; - - case UA4_IIR_NO_INT: -#if TRACING_SIO_ISR - cio_puts(" EOI\n"); -#endif - // nothing to do - tell the PIC we're done - outb(PIC1_CMD, PIC_EOI); - return; - - case UA4_IIR_MODEM_STATUS: - // shouldn't happen, but just in case.... - cio_printf("** SIO int, MSR = %02x\n", inb(UA4_MSR)); - break; - - default: - // uh-oh.... - sprint(b256, "sio isr: IIR %02x\n", ((uint32_t)iir) & 0xff); - PANIC(0, b256); - } - } - - // should never reach this point! - assert(false); -} - -/* -** PUBLIC FUNCTIONS -*/ - -/** -** sio_init() -** -** Initialize the UART chip. -*/ -void sio_init(void) -{ -#if TRACING_INIT - cio_puts(" Sio"); -#endif - - /* - ** Initialize SIO variables. - */ - - memclr((void *)inbuffer, sizeof(inbuffer)); - inlast = innext = inbuffer; - incount = 0; - - memclr((void *)outbuffer, sizeof(outbuffer)); - outlast = outnext = outbuffer; - outcount = 0; - sending = 0; - - // queue of read-blocked processes - QCREATE(QNAME); - - /* - ** Next, initialize the UART. - ** - ** Initialize the FIFOs - ** - ** this is a bizarre little sequence of operations - */ - - outb(UA5_FCR, 0x20); - outb(UA5_FCR, UA5_FCR_FIFO_RESET); // 0x00 - outb(UA5_FCR, UA5_FCR_FIFO_EN); // 0x01 - outb(UA5_FCR, UA5_FCR_FIFO_EN | UA5_FCR_RXSR); // 0x03 - outb(UA5_FCR, UA5_FCR_FIFO_EN | UA5_FCR_RXSR | UA5_FCR_TXSR); // 0x07 - - /* - ** disable interrupts - ** - ** note that we leave them disabled; sio_enable() must be - ** called to switch them back on - */ - - outb(UA4_IER, 0); - ier = 0; - - /* - ** select the divisor latch registers and set the data rate - */ - - outb(UA4_LCR, UA4_LCR_DLAB); - outb(UA4_DLL, BAUD_LOW_BYTE(DL_BAUD_9600)); - outb(UA4_DLM, BAUD_HIGH_BYTE(DL_BAUD_9600)); - - /* - ** deselect the latch registers, by setting the data - ** characteristics in the LCR - */ - - outb(UA4_LCR, UA4_LCR_WLS_8 | UA4_LCR_1_STOP_BIT | UA4_LCR_NO_PARITY); - - /* - ** Set the ISEN bit to enable the interrupt request signal, - ** and the DTR and RTS bits to enable two-way communication. - */ - - outb(UA4_MCR, UA4_MCR_ISEN | UA4_MCR_DTR | UA4_MCR_RTS); - - /* - ** Install our ISR - */ - - install_isr(VEC_COM1, sio_isr); -} - -/** -** sio_enable() -** -** Enable SIO interrupts -** -** usage: uint8_t old = sio_enable( uint8_t which ) -** -** @param which Bit mask indicating which interrupt(s) to enable -** -** @return the prior IER setting -*/ -uint8_t sio_enable(uint8_t which) -{ - uint8_t old; - - // remember the current status - - old = ier; - - // figure out what to enable - - if (which & SIO_TX) { - ier |= UA4_IER_TX_IE; - } - - if (which & SIO_RX) { - ier |= UA4_IER_RX_IE; - } - - // if there was a change, make it - - if (old != ier) { - outb(UA4_IER, ier); - } - - // return the prior settings - - return (old); -} - -/** -** sio_disable() -** -** Disable SIO interrupts -** -** usage: uint8_t old = sio_disable( uint8_t which ) -** -** @param which Bit mask indicating which interrupt(s) to disable -** -** @return the prior IER setting -*/ -uint8_t sio_disable(uint8_t which) -{ - uint8_t old; - - // remember the current status - - old = ier; - - // figure out what to disable - - if (which & SIO_TX) { - ier &= ~UA4_IER_TX_IE; - } - - if (which & SIO_RX) { - ier &= ~UA4_IER_RX_IE; - } - - // if there was a change, make it - - if (old != ier) { - outb(UA4_IER, ier); - } - - // return the prior settings - - return (old); -} - -/** -** sio_inq_length() -** -** Get the input queue length -** -** usage: int num = sio_inq_length() -** -** @return the count of characters still in the input queue -*/ -int sio_inq_length(void) -{ - return (incount); -} - -/** -** sio_readc() -** -** Get the next input character -** -** usage: int ch = sio_readc() -** -** @return the next character, or -1 if no character is available -*/ -int sio_readc(void) -{ - int ch; - - // assume there is no character available - ch = -1; - - // - // If there is a character, return it - // - - if (incount > 0) { - // take it out of the input buffer - ch = ((int)(*innext++)) & 0xff; - --incount; - - // reset the buffer variables if this was the last one - if (incount < 1) { - inlast = innext = inbuffer; - } - } - - return (ch); -} - -/** -** sio_read(buf,length) -** -** Read the entire input buffer into a user buffer of a specified size -** -** usage: int num = sio_read( char *buffer, int length ) -** -** @param buf The destination buffer -** @param length Length of the buffer -** -** @return the number of bytes copied, or 0 if no characters were available -*/ - -int sio_read(char *buf, int length) -{ - char *ptr = buf; - int copied = 0; - - // if there are no characters, just return 0 - - if (incount < 1) { - return (0); - } - - // - // We have characters. Copy as many of them into the user - // buffer as will fit. - // - - while (incount > 0 && copied < length) { - *ptr++ = *innext++ & 0xff; - if (innext > (inbuffer + BUF_SIZE)) { - innext = inbuffer; - } - --incount; - ++copied; - } - - // reset the input buffer if necessary - - if (incount < 1) { - inlast = innext = inbuffer; - } - - // return the copy count - - return (copied); -} - -/** -** sio_writec( ch ) -** -** Write a character to the serial output -** -** usage: sio_writec( int ch ) -** -** @param ch Character to be written (in the low-order 8 bits) -*/ -void sio_writec(int ch) -{ - // - // Must do LF -> CRLF mapping - // - - if (ch == '\n') { - sio_writec('\r'); - } - - // - // If we're currently transmitting, just add this to the buffer - // - - if (sending) { - *outlast++ = ch; - ++outcount; - return; - } - - // - // Not sending - must prime the pump - // - - sending = 1; - outb(UA4_TXD, ch); - - // Also must enable transmitter interrupts - - sio_enable(SIO_TX); -} - -/** -** sio_write( buffer, length ) -** -** Write a buffer of characters to the serial output -** -** usage: int num = sio_write( const char *buffer, int length ) -** -** @param buffer Buffer containing characters to write -** @param length Number of characters to write -** -** @return the number of characters copied into the SIO output buffer -*/ -int sio_write(const char *buffer, int length) -{ - int first = *buffer; - const char *ptr = buffer; - int copied = 0; - - // - // If we are currently sending, we want to append all - // the characters to the output buffer; else, we want - // to append all but the first character, and then use - // sio_writec() to send the first one out. - // - - if (!sending) { - ptr += 1; - copied++; - } - - while (copied < length && outcount < BUF_SIZE) { - *outlast++ = *ptr++; - // wrap around if necessary - if (outlast >= (outbuffer + BUF_SIZE)) { - outlast = outbuffer; - } - ++outcount; - ++copied; - } - - // - // We use sio_writec() to send out the first character, - // as it will correctly set all the other necessary - // variables for us. - // - - if (!sending) { - sio_writec(first); - } - - // Return the transfer count - - return (copied); -} - -/** -** sio_puts( buf ) -** -** Write a NUL-terminated buffer of characters to the serial output -** -** usage: int num = sio_puts( const char *buffer ) -** -** @param buffer The buffer containing a NUL-terminated string -** -** @return the count of bytes transferred -*/ -int sio_puts(const char *buffer) -{ - int n; // must be outside the loop so we can return it - - n = SLENGTH(buffer); - sio_write(buffer, n); - - return (n); -} - -/** -** sio_dump( full ) -** -** dump the contents of the SIO buffers to the console -** -** usage: sio_dump(true) or sio_dump(false) -** -** @param full Boolean indicating whether or not a "full" dump -** is being requested (which includes the contents -** of the queues) -*/ - -void sio_dump(bool_t full) -{ - int n; - char *ptr; - - // dump basic info into the status region - - cio_printf_at(48, 0, "SIO: IER %02x (%c%c%c) in %d ot %d", - ((uint32_t)ier) & 0xff, sending ? '*' : '.', - (ier & UA4_IER_TX_IE) ? 'T' : 't', - (ier & UA4_IER_RX_IE) ? 'R' : 'r', incount, outcount); - - // if we're not doing a full dump, stop now - - if (!full) { - return; - } - - // also want the queue contents, but we'll - // dump them into the scrolling region - - if (incount) { - cio_puts("SIO input queue: \""); - ptr = innext; - for (n = 0; n < incount; ++n) { - put_char_or_code(*ptr++); - } - cio_puts("\"\n"); - } - - if (outcount) { - cio_puts("SIO output queue: \""); - cio_puts(" ot: \""); - ptr = outnext; - for (n = 0; n < outcount; ++n) { - put_char_or_code(*ptr++); - } - cio_puts("\"\n"); - } -} |