/kernel/trunk/generic/include/console/chardev.h |
---|
34,10 → 34,16 |
#include <synch/waitq.h> |
#include <synch/spinlock.h> |
#define CHARDEV_BUFLEN 10 |
#define CHARDEV_BUFLEN 512 |
typedef void (* ready_func_t)(void); |
/* Character device operations interface. */ |
struct chardev_operations { |
void (* suspend)(void); /**< Suspend pushing characters. */ |
void (* resume)(void); /**< Resume pushing characters. */ |
}; |
typedef struct chardev_operations chardev_operations_t; |
/** Character input device. */ |
struct chardev { |
waitq_t wq; |
45,9 → 51,10 |
__u8 buffer[CHARDEV_BUFLEN]; |
count_t counter; |
index_t index; |
ready_func_t ready_func; /**< Function to re-enable input from the device. */ |
chardev_operations_t *op; /**< Implementation of chardev operations. */ |
}; |
extern void chardev_initialize(chardev_t *chardev, ready_func_t r); |
extern void chardev_initialize(chardev_t *chardev, chardev_operations_t *op); |
void chardev_push_character(chardev_t *chardev, __u8 ch); |
#endif /* __CHARDEV_H__ */ |
/kernel/trunk/generic/src/console/console.c |
---|
82,7 → 82,7 |
spinlock_unlock(&chardev->lock); |
interrupts_restore(ipl); |
chardev->ready_func(); |
chardev->op->resume(); |
return ch; |
} |
/kernel/trunk/generic/src/console/chardev.c |
---|
27,15 → 27,41 |
*/ |
#include <console/chardev.h> |
#include <putchar.h> |
#include <synch/waitq.h> |
#include <synch/spinlock.h> |
/** Initialize character device. */ |
void chardev_initialize(chardev_t *chardev, ready_func_t r) |
/** Initialize character device. |
* |
* @param chardev Character device. |
* @param op Implementation of character device operations. |
*/ |
void chardev_initialize(chardev_t *chardev, chardev_operations_t *op) |
{ |
waitq_initialize(&chardev->wq); |
spinlock_initialize(&chardev->lock); |
chardev->counter = 0; |
chardev->index = 0; |
chardev->ready_func = r; |
chardev->op = op; |
} |
/** Push character read from input character device. |
* |
* @param chardev Character device. |
* @param ch Character being pushed. |
*/ |
void chardev_push_character(chardev_t *chardev, __u8 ch) |
{ |
spinlock_lock(&chardev->lock); |
chardev->counter++; |
if (chardev->counter == CHARDEV_BUFLEN - 1) { |
/* buffer full => disable device interrupt */ |
chardev->op->suspend(); |
} |
putchar(ch); |
chardev->buffer[chardev->index++] = ch; |
chardev->index = chardev->index % CHARDEV_BUFLEN; /* index modulo size of buffer */ |
waitq_wakeup(&chardev->wq, WAKEUP_FIRST); |
spinlock_unlock(&chardev->lock); |
} |
/kernel/trunk/arch/amd64/src/amd64.c |
---|
102,6 → 102,7 |
void arch_post_smp_init(void) |
{ |
trap_virtual_enable_irqs(1<<IRQ_KBD); |
} |
void calibrate_delay_loop(void) |
/kernel/trunk/arch/mips32/src/drivers/keyboard.c |
---|
36,41 → 36,30 |
#include <synch/waitq.h> |
#include <typedefs.h> |
static void keyboard_enable(void); |
static void keyboard_disable(void); |
static chardev_t kbrd; |
static chardev_operations_t ops = { |
.resume = keyboard_enable, |
.suspend = keyboard_disable |
}; |
static void keyboard_enable(void); |
/** Initialize keyboard subsystem. */ |
void keyboard_init(void) |
{ |
cp0_unmask_int(KEYBOARD_IRQ); |
chardev_initialize(&kbrd, keyboard_enable); |
chardev_initialize(&kbrd, &ops); |
stdin = &kbrd; |
} |
/** Process keyboard interrupt. |
* |
* This function is called directly from the interrupt handler. |
* It feeds the keyboard buffer with characters read. When the buffer |
* is full, it simply masks the keyboard interrupt signal. |
*/ |
/** Process keyboard interrupt. */ |
void keyboard(void) |
{ |
char ch; |
spinlock_lock(&kbrd.lock); |
kbrd.counter++; |
if (kbrd.counter == CHARDEV_BUFLEN - 1) { |
/* buffer full => disable keyboard interrupt */ |
cp0_mask_int(KEYBOARD_IRQ); |
} |
ch = *((char *) KEYBOARD_ADDRESS); |
putchar(ch); |
kbrd.buffer[kbrd.index++] = ch; |
kbrd.index = kbrd.index % CHARDEV_BUFLEN; /* index modulo size of buffer */ |
waitq_wakeup(&kbrd.wq, WAKEUP_FIRST); |
spinlock_unlock(&kbrd.lock); |
chardev_push_character(&kbrd, ch); |
} |
/* Called from getc(). */ |
78,3 → 67,9 |
{ |
cp0_unmask_int(KEYBOARD_IRQ); |
} |
/* Called from getc(). */ |
void keyboard_disable(void) |
{ |
cp0_mask_int(KEYBOARD_IRQ); |
} |
/kernel/trunk/arch/ia32/src/drivers/i8042.c |
---|
35,6 → 35,8 |
#include <print.h> |
#include <synch/spinlock.h> |
#include <typedefs.h> |
#include <console/chardev.h> |
#include <console/console.h> |
/** |
* i8042 processor driver. |
55,6 → 57,15 |
static volatile int keyflags; /**< Tracking of multiple keypresses. */ |
static volatile int lockflags; /**< Tracking of multiple keys lockings. */ |
static void i8042_suspend(void); |
static void i8042_resume(void); |
static chardev_t kbrd; |
static chardev_operations_t ops = { |
.suspend = i8042_suspend, |
.resume = i8042_resume |
}; |
/** Primary meaning of scancodes. */ |
static char sc_primary_map[] = { |
SPECIAL, /* 0x00 */ |
220,6 → 231,8 |
{ |
trap_register(VECTOR_KBD, i8042_interrupt); |
spinlock_initialize(&keylock); |
chardev_initialize(&kbrd, &ops); |
stdin = &kbrd; |
} |
/** Process i8042 interrupt. |
292,8 → 305,18 |
shift = !shift; |
if (shift) |
map = sc_secondary_map; |
putchar(map[sc]); |
chardev_push_character(&kbrd, map[sc]); |
break; |
} |
spinlock_unlock(&keylock); |
} |
/* Called from getc(). */ |
void i8042_resume(void) |
{ |
} |
/* Called from getc(). */ |
void i8042_suspend(void) |
{ |
} |