Changeset 86ffa27f in mainline for kernel/arch/sparc64/src/drivers
- Timestamp:
- 2011-08-07T11:21:44Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- cc574511
- Parents:
- 15f3c3f (diff), e8067c0 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- kernel/arch/sparc64/src/drivers
- Files:
-
- 2 deleted
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/sparc64/src/drivers/kbd.c
r15f3c3f r86ffa27f 35 35 #include <arch/drivers/kbd.h> 36 36 #include <genarch/ofw/ofw_tree.h> 37 #include <genarch/ofw/fhc.h>38 37 #include <genarch/ofw/ebus.h> 39 38 #include <console/console.h> … … 51 50 #endif 52 51 53 #ifdef CONFIG_Z853054 #include <genarch/drivers/z8530/z8530.h>55 #endif56 57 52 #ifdef CONFIG_NS16550 58 53 #include <genarch/drivers/ns16550/ns16550.h> … … 60 55 61 56 #ifdef CONFIG_SUN_KBD 62 63 #ifdef CONFIG_Z853064 65 static bool kbd_z8530_init(ofw_tree_node_t *node)66 {67 const char *name = ofw_tree_node_name(node);68 69 if (str_cmp(name, "zs") != 0)70 return false;71 72 /*73 * Read 'interrupts' property.74 */75 ofw_tree_property_t *prop = ofw_tree_getprop(node, "interrupts");76 if ((!prop) || (!prop->value)) {77 printf("z8530: Unable to find interrupts property\n");78 return false;79 }80 81 uint32_t interrupts = *((uint32_t *) prop->value);82 83 /*84 * Read 'reg' property.85 */86 prop = ofw_tree_getprop(node, "reg");87 if ((!prop) || (!prop->value)) {88 printf("z8530: Unable to find reg property\n");89 return false;90 }91 92 size_t size = ((ofw_fhc_reg_t *) prop->value)->size;93 94 uintptr_t pa;95 if (!ofw_fhc_apply_ranges(node->parent,96 ((ofw_fhc_reg_t *) prop->value), &pa)) {97 printf("z8530: Failed to determine address\n");98 return false;99 }100 101 inr_t inr;102 cir_t cir;103 void *cir_arg;104 if (!ofw_fhc_map_interrupt(node->parent,105 ((ofw_fhc_reg_t *) prop->value), interrupts, &inr, &cir,106 &cir_arg)) {107 printf("z8530: Failed to determine interrupt\n");108 return false;109 }110 111 /*112 * We need to pass aligned address to hw_map().113 * However, the physical keyboard address can114 * be pretty much unaligned, depending on the115 * underlying controller.116 */117 uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE);118 size_t offset = pa - aligned_addr;119 120 z8530_t *z8530 = (z8530_t *)121 (hw_map(aligned_addr, offset + size) + offset);122 123 z8530_instance_t *z8530_instance = z8530_init(z8530, inr, cir, cir_arg);124 if (z8530_instance) {125 kbrd_instance_t *kbrd_instance = kbrd_init();126 if (kbrd_instance) {127 indev_t *sink = stdin_wire();128 indev_t *kbrd = kbrd_wire(kbrd_instance, sink);129 z8530_wire(z8530_instance, kbrd);130 }131 }132 133 /*134 * This is the necessary evil until the userspace drivers are135 * entirely self-sufficient.136 */137 sysinfo_set_item_val("kbd", NULL, true);138 sysinfo_set_item_val("kbd.inr", NULL, inr);139 sysinfo_set_item_val("kbd.address.kernel", NULL,140 (uintptr_t) z8530);141 sysinfo_set_item_val("kbd.address.physical", NULL, pa);142 sysinfo_set_item_val("kbd.type.z8530", NULL, true);143 144 return true;145 }146 147 #endif /* CONFIG_Z8530 */148 57 149 58 #ifdef CONFIG_NS16550 … … 243 152 void kbd_init(ofw_tree_node_t *node) 244 153 { 245 #ifdef CONFIG_Z8530246 kbd_z8530_init(node);247 #endif248 249 154 #ifdef CONFIG_NS16550 250 155 kbd_ns16550_init(node); -
kernel/arch/sparc64/src/drivers/niagara.c
r15f3c3f r86ffa27f 32 32 /** 33 33 * @file 34 * @brief Niagara input/output driver based on hypervisor calls.34 * @brief Niagara input/output driver based on hypervisor calls. 35 35 */ 36 36 … … 52 52 #include <genarch/srln/srln.h> 53 53 54 /* polling interval in miliseconds */54 /* Polling interval in miliseconds */ 55 55 #define POLL_INTERVAL 10000 56 56 57 /* device instance */57 /* Device instance */ 58 58 static niagara_instance_t *instance = NULL; 59 59 60 static void niagara_putchar(outdev_t *, const wchar_t , bool);61 62 /** character device operations */60 static void niagara_putchar(outdev_t *, const wchar_t); 61 62 /** Character device operations */ 63 63 static outdev_operations_t niagara_ops = { 64 64 .write = niagara_putchar, … … 66 66 }; 67 67 68 /* 68 /** 69 69 * The driver uses hypercalls to print characters to the console. Since the 70 70 * hypercall cannot be performed from the userspace, we do this: 71 * The kernel "little brother" driver (which will be present no matter what the 72 * DDI architecture is - as we need the kernel part for the kconsole) 71 * 72 * The kernel "little brother" driver (which will be present no matter what 73 * the DDI architecture is -- as we need the kernel part for the kconsole) 73 74 * defines a shared buffer. Kernel walks through the buffer (in the same thread 74 75 * which is used for polling the keyboard) and prints any pending characters 75 * to the console (using hypercalls). The userspace fb server maps this shared 76 * buffer to its address space and output operation it does is performed using 77 * the mapped buffer. The shared buffer definition follows. 78 */ 79 #define OUTPUT_BUFFER_SIZE ((PAGE_SIZE) - 2 * 8) 76 * to the console (using hypercalls). 77 * 78 * The userspace fb server maps this shared buffer to its address space and 79 * output operation it does is performed using the mapped buffer. The shared 80 * buffer definition follows. 81 */ 82 #define OUTPUT_BUFFER_SIZE ((PAGE_SIZE) - 2 * 8) 83 80 84 static volatile struct { 81 85 uint64_t read_ptr; 82 86 uint64_t write_ptr; 83 87 char data[OUTPUT_BUFFER_SIZE]; 84 } 85 __attribute__ ((packed)) 86 __attribute__ ((aligned(PAGE_SIZE))) 87 output_buffer; 88 } __attribute__ ((packed)) __attribute__ ((aligned(PAGE_SIZE))) output_buffer; 89 90 static parea_t outbuf_parea; 88 91 89 92 /** 90 93 * Analogous to the output_buffer, see the previous definition. 91 94 */ 92 #define INPUT_BUFFER_SIZE ((PAGE_SIZE) - 2 * 8) 95 #define INPUT_BUFFER_SIZE ((PAGE_SIZE) - 2 * 8) 96 93 97 static volatile struct { 94 98 uint64_t write_ptr; 95 99 uint64_t read_ptr; 96 100 char data[INPUT_BUFFER_SIZE]; 97 } 98 __attribute__ ((packed)) 99 __attribute__ ((aligned(PAGE_SIZE))) 100 input_buffer; 101 102 103 /** Writes a single character to the standard output. */ 101 } __attribute__ ((packed)) __attribute__ ((aligned(PAGE_SIZE))) input_buffer; 102 103 static parea_t inbuf_parea; 104 105 /** Write a single character to the standard output. */ 104 106 static inline void do_putchar(const char c) { 105 /* repeat until the buffer is non-full */ 106 while (__hypercall_fast1(CONS_PUTCHAR, c) == HV_EWOULDBLOCK) 107 ; 108 } 109 110 /** Writes a single character to the standard output. */ 111 static void niagara_putchar(outdev_t *dev, const wchar_t ch, bool silent) 112 { 113 if (silent) 114 return; 115 116 do_putchar(ch); 117 if (ch == '\n') 118 do_putchar('\r'); 119 } 120 121 /** 122 * Function regularly called by the keyboard polling thread. Asks the 123 * hypervisor whether there is any unread character. If so, it picks it up 124 * and sends it to the upper layers of HelenOS. 125 * 126 * Apart from that, it also checks whether the userspace output driver has 127 * pushed any characters to the output buffer. If so, it prints them. 128 */ 129 static void niagara_poll(niagara_instance_t *instance) 130 { 131 /* print any pending characters from the shared buffer to the console */ 107 /* Repeat until the buffer is non-full */ 108 while (__hypercall_fast1(CONS_PUTCHAR, c) == HV_EWOULDBLOCK); 109 } 110 111 /** Write a single character to the standard output. */ 112 static void niagara_putchar(outdev_t *dev, const wchar_t ch) 113 { 114 if ((!outbuf_parea.mapped) || (console_override)) { 115 do_putchar(ch); 116 if (ch == '\n') 117 do_putchar('\r'); 118 } 119 } 120 121 /** Poll keyboard and print pending characters. 122 * 123 * Ask the hypervisor whether there is any unread character. If so, 124 * pick it up and send it to the indev layer. 125 * 126 * Check whether the userspace output driver has pushed any 127 * characters to the output buffer and eventually print them. 128 * 129 */ 130 static void niagara_poll(void) 131 { 132 /* 133 * Print any pending characters from the 134 * shared buffer to the console. 135 */ 136 132 137 while (output_buffer.read_ptr != output_buffer.write_ptr) { 133 138 do_putchar(output_buffer.data[output_buffer.read_ptr]); 134 139 output_buffer.read_ptr = 135 ((output_buffer.read_ptr) + 1) % OUTPUT_BUFFER_SIZE; 136 } 137 140 ((output_buffer.read_ptr) + 1) % OUTPUT_BUFFER_SIZE; 141 } 142 143 /* 144 * Read character from keyboard. 145 */ 146 138 147 uint64_t c; 139 140 /* read character from keyboard, send it to upper layers of HelenOS */141 148 if (__hypercall_fast_ret1(0, 0, 0, 0, 0, CONS_GETCHAR, &c) == HV_EOK) { 142 if (!silent) { 143 /* kconsole active, send the character to kernel */ 149 if ((!inbuf_parea.mapped) || (console_override)) { 150 /* 151 * Kernel console is active, send 152 * the character to kernel. 153 */ 144 154 indev_push_character(instance->srlnin, c); 145 155 } else { 146 /* kconsole inactive, send the character to uspace driver */ 156 /* 157 * Kernel console is inactive, send 158 * the character to uspace driver. 159 */ 147 160 input_buffer.data[input_buffer.write_ptr] = (char) c; 148 161 input_buffer.write_ptr = 149 ((input_buffer.write_ptr) + 1) % INPUT_BUFFER_SIZE;162 ((input_buffer.write_ptr) + 1) % INPUT_BUFFER_SIZE; 150 163 } 151 164 } 152 165 } 153 166 154 /** 155 * Polling thread function.156 */ 157 static void kniagarapoll(void * instance) {167 /** Polling thread function. 168 * 169 */ 170 static void kniagarapoll(void *arg) { 158 171 while (true) { 159 niagara_poll( instance);172 niagara_poll(); 160 173 thread_usleep(POLL_INTERVAL); 161 174 } 162 175 } 163 176 164 /** 165 * Initializes the input/output subsystem so that the Niagara standard 166 * input/output is used. 177 /** Initialize the input/output subsystem 178 * 167 179 */ 168 180 static void niagara_init(void) … … 172 184 173 185 instance = malloc(sizeof(niagara_instance_t), FRAME_ATOMIC); 174 175 if (instance) { 176 instance->thread = thread_create(kniagarapoll, instance, TASK, 0, 177 "kniagarapoll", true); 178 179 if (!instance->thread) { 180 free(instance); 181 instance = NULL; 182 return; 183 } 184 } 185 186 instance->thread = thread_create(kniagarapoll, NULL, TASK, 0, 187 "kniagarapoll", true); 188 189 if (!instance->thread) { 190 free(instance); 191 instance = NULL; 192 return; 193 } 194 186 195 instance->srlnin = NULL; 187 196 188 197 output_buffer.read_ptr = 0; 189 198 output_buffer.write_ptr = 0; 190 199 input_buffer.write_ptr = 0; 191 200 input_buffer.read_ptr = 0; 192 201 193 202 /* 194 203 * Set sysinfos and pareas so that the userspace counterpart of the 195 204 * niagara fb and kbd driver can communicate with kernel using shared 196 205 * buffers. 197 */198 206 */ 207 199 208 sysinfo_set_item_val("fb.kind", NULL, 5); 200 209 201 210 sysinfo_set_item_val("niagara.outbuf.address", NULL, 202 KA2PA(&output_buffer));211 KA2PA(&output_buffer)); 203 212 sysinfo_set_item_val("niagara.outbuf.size", NULL, 204 PAGE_SIZE);213 PAGE_SIZE); 205 214 sysinfo_set_item_val("niagara.outbuf.datasize", NULL, 206 OUTPUT_BUFFER_SIZE);207 215 OUTPUT_BUFFER_SIZE); 216 208 217 sysinfo_set_item_val("niagara.inbuf.address", NULL, 209 KA2PA(&input_buffer));218 KA2PA(&input_buffer)); 210 219 sysinfo_set_item_val("niagara.inbuf.size", NULL, 211 PAGE_SIZE);220 PAGE_SIZE); 212 221 sysinfo_set_item_val("niagara.inbuf.datasize", NULL, 213 INPUT_BUFFER_SIZE); 214 215 static parea_t outbuf_parea; 222 INPUT_BUFFER_SIZE); 223 216 224 outbuf_parea.pbase = (uintptr_t) (KA2PA(&output_buffer)); 217 225 outbuf_parea.frames = 1; 218 226 outbuf_parea.unpriv = false; 227 outbuf_parea.mapped = false; 219 228 ddi_parea_register(&outbuf_parea); 220 221 static parea_t inbuf_parea; 229 222 230 inbuf_parea.pbase = (uintptr_t) (KA2PA(&input_buffer)); 223 231 inbuf_parea.frames = 1; 224 232 inbuf_parea.unpriv = false; 233 inbuf_parea.mapped = false; 225 234 ddi_parea_register(&inbuf_parea); 226 235 227 236 outdev_t *niagara_dev = malloc(sizeof(outdev_t), FRAME_ATOMIC); 228 237 outdev_initialize("niagara_dev", niagara_dev, &niagara_ops); … … 230 239 } 231 240 232 /** 233 * A public function which initializes input from the Niagara console.241 /** Initialize input from the Niagara console. 242 * 234 243 */ 235 244 niagara_instance_t *niagarain_init(void) 236 245 { 237 246 niagara_init(); 238 247 239 248 if (instance) { 240 249 srln_instance_t *srln_instance = srln_init(); … … 242 251 indev_t *sink = stdin_wire(); 243 252 indev_t *srln = srln_wire(srln_instance, sink); 244 245 // wire std. input to niagara 253 246 254 instance->srlnin = srln; 247 255 thread_ready(instance->thread); 248 256 } 249 257 } 258 250 259 return instance; 251 260 }
Note:
See TracChangeset
for help on using the changeset viewer.
