Changeset 013c4d6 in mainline
- Timestamp:
- 2009-02-19T23:55:23Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f32d90b
- Parents:
- d1eece6
- Location:
- kernel
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/ia64/src/ia64.c
rd1eece6 r013c4d6 66 66 /* NS16550 as a COM 1 */ 67 67 #define NS16550_IRQ (4 + LEGACY_INTERRUPT_BASE) 68 #define NS16550_PORT 0x3f869 68 70 69 bootinfo_t *bootinfo; … … 165 164 166 165 #ifdef CONFIG_NS16550 167 ns16550_init(kbd, NS16550_PORT, NS16550_IRQ, NULL, NULL); 166 (void) ns16550_init((ns16550_t *)NS16550_BASE, kbd, NS16550_IRQ, NULL, 167 NULL); 168 168 #else 169 169 devno_t mouse = device_assign_devno(); … … 250 250 void arch_reboot(void) 251 251 { 252 pio_write_8( 0x64, 0xfe);252 pio_write_8((ioport8_t *)0x64, 0xfe); 253 253 while (1) 254 254 ; -
kernel/arch/ia64/src/smp/smp.c
rd1eece6 r013c4d6 52 52 #include <ddi/irq.h> 53 53 #include <ddi/device.h> 54 #include <arch/drivers/ega.h>55 54 #include <arch/bootinfo.h> 56 55 #include <genarch/kbd/i8042.h> -
kernel/genarch/include/drivers/legacy/ia32/io.h
rd1eece6 r013c4d6 40 40 #include <arch/types.h> 41 41 42 #define i8042_BASE ((ioport8_t *)0x60)42 #define I8042_BASE ((ioport8_t *)0x60) 43 43 44 44 #define EGA_VIDEORAM 0xb8000 45 45 #define EGA_BASE ((ioport8_t *)0x3d4) 46 47 #define NS16550_BASE ((ioport8_t *)0x3f8) 46 48 47 49 #endif -
kernel/genarch/include/kbd/i8042.h
rd1eece6 r013c4d6 37 37 38 38 #include <arch/types.h> 39 #include < console/chardev.h>39 #include <typedefs.h> 40 40 41 41 struct i8042 { … … 53 53 extern void i8042_grab(void); 54 54 extern void i8042_release(void); 55 extern char i8042_key_read(chardev_t *d);56 55 57 56 #endif -
kernel/genarch/include/kbd/ns16550.h
rd1eece6 r013c4d6 38 38 #define KERN_NS16550_H_ 39 39 40 #include <console/chardev.h>41 40 #include <ddi/irq.h> 42 #include <ipc/irq.h>43 44 extern void ns16550_init(devno_t, uintptr_t, inr_t, cir_t, void *);45 extern void ns16550_poll(void);46 extern void ns16550_grab(void);47 extern void ns16550_release(void);48 extern char ns16550_key_read(chardev_t *);49 extern irq_ownership_t ns16550_claim(void *);50 extern void ns16550_irq_handler(irq_t *);51 52 41 #include <arch/types.h> 53 42 #include <arch/drivers/kbd.h> 54 55 /* NS16550 registers */56 #define RBR_REG 0 /** Receiver Buffer Register. */57 #define IER_REG 1 /** Interrupt Enable Register. */58 #define IIR_REG 2 /** Interrupt Ident Register (read). */59 #define FCR_REG 2 /** FIFO control register (write). */60 #define LCR_REG 3 /** Line Control register. */61 #define MCR_REG 4 /** Modem Control Register. */62 #define LSR_REG 5 /** Line Status Register. */63 43 64 44 #define IER_ERBFI 0x01 /** Enable Receive Buffer Full Interrupt. */ … … 68 48 #define MCR_OUT2 0x08 /** OUT2. */ 69 49 50 /** NS16550 registers. */ 51 struct ns16550 { 52 ioport8_t rbr; /**< Receiver Buffer Register. */ 53 ioport8_t ier; /**< Interrupt Enable Register. */ 54 union { 55 ioport8_t iir; /**< Interrupt Ident Register (read). */ 56 ioport8_t fcr; /**< FIFO control register (write). */ 57 } __attribute__ ((packed)); 58 ioport8_t lcr; /**< Line Control register. */ 59 ioport8_t mcr; /**< Modem Control Register. */ 60 ioport8_t lsr; /**< Line Status Register. */ 61 } __attribute__ ((packed)); 62 typedef struct ns16550 ns16550_t; 63 70 64 /** Structure representing the ns16550 device. */ 71 typedef struct {65 typedef struct ns16550_instance { 72 66 devno_t devno; 73 /** Memory mapped registers of the ns16550. */74 volatile ioport_t io_port;75 } ns16550_ t;67 ns16550_t *ns16550; 68 irq_t *irq; 69 } ns16550_instance_t; 76 70 77 static inline uint8_t ns16550_rbr_read(ns16550_t *dev) 78 { 79 return pio_read_8(dev->io_port + RBR_REG); 80 } 81 static inline void ns16550_rbr_write(ns16550_t *dev, uint8_t v) 82 { 83 pio_write_8(dev->io_port + RBR_REG, v); 84 } 85 86 static inline uint8_t ns16550_ier_read(ns16550_t *dev) 87 { 88 return pio_read_8(dev->io_port + IER_REG); 89 } 90 91 static inline void ns16550_ier_write(ns16550_t *dev, uint8_t v) 92 { 93 pio_write_8(dev->io_port + IER_REG, v); 94 } 95 96 static inline uint8_t ns16550_iir_read(ns16550_t *dev) 97 { 98 return pio_read_8(dev->io_port + IIR_REG); 99 } 100 101 static inline void ns16550_fcr_write(ns16550_t *dev, uint8_t v) 102 { 103 pio_write_8(dev->io_port + FCR_REG, v); 104 } 105 106 static inline uint8_t ns16550_lcr_read(ns16550_t *dev) 107 { 108 return pio_read_8(dev->io_port + LCR_REG); 109 } 110 111 static inline void ns16550_lcr_write(ns16550_t *dev, uint8_t v) 112 { 113 pio_write_8(dev->io_port + LCR_REG, v); 114 } 115 116 static inline uint8_t ns16550_lsr_read(ns16550_t *dev) 117 { 118 return pio_read_8(dev->io_port + LSR_REG); 119 } 120 121 static inline uint8_t ns16550_mcr_read(ns16550_t *dev) 122 { 123 return pio_read_8(dev->io_port + MCR_REG); 124 } 125 126 static inline void ns16550_mcr_write(ns16550_t *dev, uint8_t v) 127 { 128 pio_write_8(dev->io_port + MCR_REG, v); 129 } 71 extern bool ns16550_init(ns16550_t *, devno_t, inr_t, cir_t, void *); 72 extern void ns16550_grab(void); 73 extern void ns16550_release(void); 74 extern irq_ownership_t ns16550_claim(void *); 75 extern void ns16550_irq_handler(irq_t *); 130 76 131 77 #endif -
kernel/genarch/src/kbd/i8042.c
rd1eece6 r013c4d6 53 53 54 54 i8042_instance_t lgcy_i8042_instance = { 55 .i8042 = (i8042_t *) i8042_BASE,55 .i8042 = (i8042_t *) I8042_BASE, 56 56 }; 57 57 … … 89 89 .suspend = i8042_suspend, 90 90 .resume = i8042_resume, 91 .read = i8042_key_read92 91 }; 93 92 … … 229 228 } 230 229 231 char i8042_key_read(chardev_t *d)232 {233 i8042_t *dev = lgcy_i8042_instance.i8042;234 char ch;235 236 while (!(ch = active_read_buff_read())) {237 uint8_t x;238 239 while (!(pio_read_8(&dev->status) & i8042_BUFFER_FULL_MASK))240 ;241 242 x = pio_read_8(&dev->data);243 if (x & KEY_RELEASE)244 key_released(x ^ KEY_RELEASE);245 else246 active_read_key_pressed(x);247 }248 return ch;249 }250 251 230 /** @} 252 231 */ -
kernel/genarch/src/kbd/ns16550.c
rd1eece6 r013c4d6 51 51 #include <sysinfo/sysinfo.h> 52 52 #include <synch/spinlock.h> 53 #include <mm/slab.h> 53 54 54 55 #define LSR_DATA_READY 0x01 55 56 56 /** Structure representing the ns16550. */ 57 static ns16550_t ns16550; 58 59 /** Structure for ns16550's IRQ. */ 60 static irq_t ns16550_irq; 57 static irq_t *ns16550_irq; 61 58 62 59 /* … … 71 68 .suspend = ns16550_suspend, 72 69 .resume = ns16550_resume, 73 .read = ns16550_key_read74 70 }; 75 76 void ns16550_interrupt(void);77 71 78 72 /** Initialize keyboard and service interrupts using kernel routine */ … … 80 74 { 81 75 ipl_t ipl = interrupts_disable(); 82 83 ns16550_ier_write(&ns16550, IER_ERBFI); /* enable receiver interrupt */ 84 85 while (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) 86 (void) ns16550_rbr_read(&ns16550); 87 88 spinlock_lock(&ns16550_irq.lock); 89 ns16550_irq.notif_cfg.notify = false; 90 spinlock_unlock(&ns16550_irq.lock); 76 spinlock_lock(&ns16550_irq->lock); 77 ns16550_irq->notif_cfg.notify = false; 78 spinlock_unlock(&ns16550_irq->lock); 91 79 interrupts_restore(ipl); 92 80 } … … 96 84 { 97 85 ipl_t ipl = interrupts_disable(); 98 spinlock_lock(&ns16550_irq .lock);99 if (ns16550_irq .notif_cfg.answerbox)100 ns16550_irq .notif_cfg.notify = true;101 spinlock_unlock(&ns16550_irq .lock);86 spinlock_lock(&ns16550_irq->lock); 87 if (ns16550_irq->notif_cfg.answerbox) 88 ns16550_irq->notif_cfg.notify = true; 89 spinlock_unlock(&ns16550_irq->lock); 102 90 interrupts_restore(ipl); 103 91 } … … 105 93 /** Initialize ns16550. 106 94 * 95 * @param dev Addrress of the beginning of the device in I/O space. 107 96 * @param devno Device number. 108 * @param port Virtual/IO address of device's registers.109 97 * @param inr Interrupt number. 110 98 * @param cir Clear interrupt function. 111 99 * @param cir_arg First argument to cir. 112 */ 113 void 114 ns16550_init(devno_t devno, ioport_t port, inr_t inr, cir_t cir, void *cir_arg) 115 { 100 * 101 * @return True on success, false on failure. 102 */ 103 bool 104 ns16550_init(ns16550_t *dev, devno_t devno, inr_t inr, cir_t cir, void *cir_arg) 105 { 106 ns16550_instance_t *instance; 107 irq_t *irq; 108 116 109 chardev_initialize("ns16550_kbd", &kbrd, &ops); 117 110 stdin = &kbrd; 118 111 119 ns16550.devno = devno; 120 ns16550.io_port = port; 121 122 irq_initialize(&ns16550_irq); 123 ns16550_irq.devno = devno; 124 ns16550_irq.inr = inr; 125 ns16550_irq.claim = ns16550_claim; 126 ns16550_irq.handler = ns16550_irq_handler; 127 ns16550_irq.cir = cir; 128 ns16550_irq.cir_arg = cir_arg; 129 irq_register(&ns16550_irq); 130 131 while ((ns16550_lsr_read(&ns16550) & LSR_DATA_READY)) 132 ns16550_rbr_read(&ns16550); 112 instance = malloc(sizeof(ns16550_instance_t), FRAME_ATOMIC); 113 if (!instance) 114 return false; 115 116 irq = malloc(sizeof(irq_t), FRAME_ATOMIC); 117 if (!irq) { 118 free(instance); 119 return false; 120 } 121 122 instance->devno = devno; 123 instance->ns16550 = dev; 124 instance->irq = irq; 125 126 irq_initialize(irq); 127 irq->devno = devno; 128 irq->inr = inr; 129 irq->claim = ns16550_claim; 130 irq->handler = ns16550_irq_handler; 131 irq->instance = instance; 132 irq->cir = cir; 133 irq->cir_arg = cir_arg; 134 irq_register(irq); 135 136 ns16550_irq = irq; /* TODO: remove me soon */ 137 138 while ((pio_read_8(&dev->lsr) & LSR_DATA_READY)) 139 (void) pio_read_8(&dev->rbr); 133 140 134 141 sysinfo_set_item_val("kbd", NULL, true); … … 136 143 sysinfo_set_item_val("kbd.devno", NULL, devno); 137 144 sysinfo_set_item_val("kbd.inr", NULL, inr); 138 sysinfo_set_item_val("kbd.address.virtual", NULL, port);139 sysinfo_set_item_val("kbd.port", NULL, port);145 sysinfo_set_item_val("kbd.address.virtual", NULL, (uintptr_t) dev); 146 sysinfo_set_item_val("kbd.port", NULL, (uintptr_t) dev); 140 147 141 148 /* Enable interrupts */ 142 ns16550_ier_write(&ns16550, IER_ERBFI); 143 ns16550_mcr_write(&ns16550, MCR_OUT2); 144 145 uint8_t c; 146 // This switches rbr & ier to mode when accept baudrate constant 147 c = ns16550_lcr_read(&ns16550); 148 ns16550_lcr_write(&ns16550, 0x80 | c); 149 ns16550_rbr_write(&ns16550, 0x0c); 150 ns16550_ier_write(&ns16550, 0x00); 151 ns16550_lcr_write(&ns16550, c); 149 pio_write_8(&dev->ier, IER_ERBFI); 150 pio_write_8(&dev->mcr, MCR_OUT2); 152 151 153 152 ns16550_grab(); 154 } 155 156 /** Process ns16550 interrupt. */ 157 void ns16550_interrupt(void) 158 { 159 ns16550_poll(); 153 154 return true; 160 155 } 161 156 … … 170 165 } 171 166 172 173 char ns16550_key_read(chardev_t *d) 174 { 175 char ch; 176 177 while(!(ch = active_read_buff_read())) { 178 uint8_t x; 179 while (!(ns16550_lsr_read(&ns16550) & LSR_DATA_READY)); 180 181 x = ns16550_rbr_read(&ns16550); 182 183 if (x != IGNORE_CODE) { 184 if (x & KEY_RELEASE) 185 key_released(x ^ KEY_RELEASE); 186 else 187 active_read_key_pressed(x); 188 } 167 irq_ownership_t ns16550_claim(void *instance) 168 { 169 ns16550_instance_t *ns16550_instance = instance; 170 ns16550_t *dev = ns16550_instance->ns16550; 171 172 if (pio_read_8(&dev->lsr) & LSR_DATA_READY) 173 return IRQ_ACCEPT; 174 else 175 return IRQ_DECLINE; 176 } 177 178 void ns16550_irq_handler(irq_t *irq) 179 { 180 if (irq->notif_cfg.notify && irq->notif_cfg.answerbox) { 181 /* 182 * This will hopefully go to the IRQ dispatch code soon. 183 */ 184 ipc_irq_send_notif(irq); 185 return; 189 186 } 190 return ch; 191 } 192 193 /** Poll for key press and release events. 194 * 195 * This function can be used to implement keyboard polling. 196 */ 197 void ns16550_poll(void) 198 { 199 while (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) { 187 188 ns16550_instance_t *ns16550_instance = irq->instance; 189 ns16550_t *dev = ns16550_instance->ns16550; 190 191 if (pio_read_8(&dev->lsr) & LSR_DATA_READY) { 200 192 uint8_t x; 201 193 202 x = ns16550_rbr_read(&ns16550);194 x = pio_read_8(&dev->rbr); 203 195 204 196 if (x != IGNORE_CODE) { … … 209 201 } 210 202 } 211 } 212 213 irq_ownership_t ns16550_claim(void *instance) 214 { 215 return (ns16550_lsr_read(&ns16550) & LSR_DATA_READY); 216 } 217 218 void ns16550_irq_handler(irq_t *irq) 219 { 220 if (irq->notif_cfg.notify && irq->notif_cfg.answerbox) 221 ipc_irq_send_notif(irq); 222 else 223 ns16550_interrupt(); 203 224 204 } 225 205
Note:
See TracChangeset
for help on using the changeset viewer.