Rev 4070 | Rev 4111 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4070 | Rev 4071 | ||
---|---|---|---|
Line 71... | Line 71... | ||
71 | * Key into the SRAM table of contents which identifies the entry |
71 | * Key into the SRAM table of contents which identifies the entry |
72 | * describing the OBP console buffer. It is worth mentioning |
72 | * describing the OBP console buffer. It is worth mentioning |
73 | * that the OBP console buffer is not the only console buffer |
73 | * that the OBP console buffer is not the only console buffer |
74 | * which can be used. It is, however, used because when the kernel |
74 | * which can be used. It is, however, used because when the kernel |
75 | * is running, the OBP buffer is not used by OBP any more but OBP |
75 | * is running, the OBP buffer is not used by OBP any more but OBP |
76 | * has already made neccessary arangements so that the output will |
76 | * has already made necessary arrangements so that the output will |
77 | * be read from the OBP buffer and input will go to the OBP buffer. |
77 | * be read from the OBP buffer and input will go to the OBP buffer. |
78 | * Therefore HelenOS needs to make no such arrangements any more. |
78 | * Therefore HelenOS needs to make no such arrangements any more. |
79 | */ |
79 | */ |
80 | #define CONSOLE_KEY "OBPCONS" |
80 | #define CONSOLE_KEY "OBPCONS" |
81 | 81 | ||
Line 94... | Line 94... | ||
94 | /* |
94 | /* |
95 | * Returns a pointer to the object of a given type which is placed at the given |
95 | * Returns a pointer to the object of a given type which is placed at the given |
96 | * offset from the console buffer beginning. |
96 | * offset from the console buffer beginning. |
97 | */ |
97 | */ |
98 | #define SGCN_BUFFER(type, offset) \ |
98 | #define SGCN_BUFFER(type, offset) \ |
99 | ((type *) (sgcn_buffer_begin + (offset))) |
99 | ((type *) (sgcn_buffer_begin + (offset))) |
100 | 100 | ||
101 | /** Returns a pointer to the console buffer header. */ |
101 | /** Returns a pointer to the console buffer header. */ |
102 | #define SGCN_BUFFER_HEADER (SGCN_BUFFER(sgcn_buffer_header_t, 0)) |
102 | #define SGCN_BUFFER_HEADER (SGCN_BUFFER(sgcn_buffer_header_t, 0)) |
103 | 103 | ||
104 | /** defined in drivers/kbd.c */ |
104 | /** defined in drivers/kbd.c */ |
Line 143... | Line 143... | ||
143 | }; |
143 | }; |
144 | 144 | ||
145 | /** SGCN character device */ |
145 | /** SGCN character device */ |
146 | chardev_t sgcn_io; |
146 | chardev_t sgcn_io; |
147 | 147 | ||
- | 148 | /** Address of the chardev, which is connected to SGCN. */ |
|
- | 149 | static chardev_t *sgcnout; |
|
- | 150 | ||
148 | /** |
151 | /** |
149 | * Set some sysinfo values (SRAM address and SRAM size). |
152 | * Set some sysinfo values (SRAM address and SRAM size). |
150 | */ |
153 | */ |
151 | static void register_sram(uintptr_t sram_begin_physical) |
154 | static void register_sram(uintptr_t sram_begin_physical) |
152 | { |
155 | { |
153 | sysinfo_set_item_val("sram.area.size", NULL, MAPPED_AREA_SIZE); |
156 | sysinfo_set_item_val("sram.area.size", NULL, MAPPED_AREA_SIZE); |
154 | sysinfo_set_item_val("sram.address.physical", NULL, |
157 | sysinfo_set_item_val("sram.address.physical", NULL, |
155 | sram_begin_physical); |
158 | sram_begin_physical); |
156 | } |
159 | } |
157 | 160 | ||
158 | /** |
161 | /** |
159 | * Initializes the starting address of SRAM. |
162 | * Initializes the starting address of SRAM. |
160 | * |
163 | * |
161 | * The SRAM starts 0x900000 + C bytes behind the SBBC start in the |
164 | * The SRAM starts 0x900000 + C bytes behind the SBBC start in the |
162 | * physical memory, where C is the value read from the "iosram-toc" |
165 | * physical memory, where C is the value read from the "iosram-toc" |
163 | * property of the "/chosen" OBP node. The sram_begin variable will |
166 | * property of the "/chosen" OBP node. The sram_begin variable will |
164 | * be set to the virtual address which maps to the SRAM physical |
167 | * be set to the virtual address which maps to the SRAM physical |
165 | * address. |
168 | * address. |
166 | * |
- | |
167 | * It also registers the physical area of SRAM and sets some sysinfo |
- | |
168 | * values (SRAM address and SRAM size). |
- | |
169 | */ |
169 | */ |
170 | static void init_sram_begin(void) |
170 | static void init_sram_begin(void) |
171 | { |
171 | { |
172 | ofw_tree_node_t *chosen; |
172 | ofw_tree_node_t *chosen; |
173 | ofw_tree_property_t *iosram_toc; |
173 | ofw_tree_property_t *iosram_toc; |
Line 182... | Line 182... | ||
182 | panic("Cannot find property 'iosram-toc'."); |
182 | panic("Cannot find property 'iosram-toc'."); |
183 | if (!iosram_toc->value) |
183 | if (!iosram_toc->value) |
184 | panic("Cannot find SRAM TOC."); |
184 | panic("Cannot find SRAM TOC."); |
185 | 185 | ||
186 | sram_begin_physical = SBBC_START + SBBC_SRAM_OFFSET |
186 | sram_begin_physical = SBBC_START + SBBC_SRAM_OFFSET |
187 | + *((uint32_t *) iosram_toc->value); |
187 | + *((uint32_t *) iosram_toc->value); |
188 | sram_begin = hw_map(sram_begin_physical, MAPPED_AREA_SIZE); |
188 | sram_begin = hw_map(sram_begin_physical, MAPPED_AREA_SIZE); |
189 | 189 | ||
190 | register_sram(sram_begin_physical); |
190 | register_sram(sram_begin_physical); |
191 | } |
191 | } |
192 | 192 | ||
Line 216... | Line 216... | ||
216 | ASSERT(i < MAX_TOC_ENTRIES); |
216 | ASSERT(i < MAX_TOC_ENTRIES); |
217 | 217 | ||
218 | sgcn_buffer_begin = sram_begin + SRAM_TOC->keys[i].offset; |
218 | sgcn_buffer_begin = sram_begin + SRAM_TOC->keys[i].offset; |
219 | 219 | ||
220 | sysinfo_set_item_val("sram.buffer.offset", NULL, |
220 | sysinfo_set_item_val("sram.buffer.offset", NULL, |
221 | SRAM_TOC->keys[i].offset); |
221 | SRAM_TOC->keys[i].offset); |
222 | } |
222 | } |
223 | 223 | ||
224 | /** |
224 | /** |
225 | * Default suspend/resume operation for the input device. |
225 | * Default suspend/resume operation for the input device. |
226 | */ |
226 | */ |
Line 239... | Line 239... | ||
239 | uint32_t end = SGCN_BUFFER_HEADER->out_end; |
239 | uint32_t end = SGCN_BUFFER_HEADER->out_end; |
240 | uint32_t size = end - begin; |
240 | uint32_t size = end - begin; |
241 | 241 | ||
242 | /* we need pointers to volatile variables */ |
242 | /* we need pointers to volatile variables */ |
243 | volatile char *buf_ptr = (volatile char *) |
243 | volatile char *buf_ptr = (volatile char *) |
244 | SGCN_BUFFER(char, SGCN_BUFFER_HEADER->out_wrptr); |
244 | SGCN_BUFFER(char, SGCN_BUFFER_HEADER->out_wrptr); |
245 | volatile uint32_t *out_wrptr_ptr = &(SGCN_BUFFER_HEADER->out_wrptr); |
245 | volatile uint32_t *out_wrptr_ptr = &(SGCN_BUFFER_HEADER->out_wrptr); |
246 | volatile uint32_t *out_rdptr_ptr = &(SGCN_BUFFER_HEADER->out_rdptr); |
246 | volatile uint32_t *out_rdptr_ptr = &(SGCN_BUFFER_HEADER->out_rdptr); |
247 | 247 | ||
248 | /* |
248 | /* |
249 | * Write the character and increment the write pointer modulo the |
249 | * Write the character and increment the write pointer modulo the |
Line 317... | Line 317... | ||
317 | { |
317 | { |
318 | uint32_t begin = SGCN_BUFFER_HEADER->in_begin; |
318 | uint32_t begin = SGCN_BUFFER_HEADER->in_begin; |
319 | uint32_t end = SGCN_BUFFER_HEADER->in_end; |
319 | uint32_t end = SGCN_BUFFER_HEADER->in_end; |
320 | uint32_t size = end - begin; |
320 | uint32_t size = end - begin; |
321 | 321 | ||
322 | spinlock_lock(&sgcn_input_lock); |
- | |
323 | - | ||
324 | ipl_t ipl = interrupts_disable(); |
- | |
325 | - | ||
326 | if (kbd_disabled) { |
322 | if (kbd_disabled) |
327 | interrupts_restore(ipl); |
- | |
328 | return; |
323 | return; |
329 | } |
324 | |
- | 325 | spinlock_lock(&sgcn_input_lock); |
|
330 | 326 | ||
331 | /* we need pointers to volatile variables */ |
327 | /* we need pointers to volatile variables */ |
332 | volatile char *buf_ptr = (volatile char *) |
328 | volatile char *buf_ptr = (volatile char *) |
333 | SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr); |
329 | SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr); |
334 | volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr); |
330 | volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr); |
335 | volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr); |
331 | volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr); |
336 | 332 | ||
337 | while (*in_rdptr_ptr != *in_wrptr_ptr) { |
333 | while (*in_rdptr_ptr != *in_wrptr_ptr) { |
338 | 334 | ||
339 | buf_ptr = (volatile char *) |
335 | buf_ptr = (volatile char *) |
340 | SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr); |
336 | SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr); |
341 | char c = *buf_ptr; |
337 | char c = *buf_ptr; |
342 | *in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin; |
338 | *in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin; |
343 | 339 | ||
344 | if (c == '\r') { |
340 | if (sgcnout) |
345 | c = '\n'; |
- | |
346 | } |
- | |
347 | chardev_push_character(&sgcn_io, c); |
341 | chardev_push_character(sgcnout, c); |
348 | } |
342 | } |
349 | 343 | ||
350 | interrupts_restore(ipl); |
- | |
351 | spinlock_unlock(&sgcn_input_lock); |
344 | spinlock_unlock(&sgcn_input_lock); |
352 | } |
345 | } |
353 | 346 | ||
354 | /** |
347 | /** |
355 | * Polling thread function. |
348 | * Polling thread function. |
Line 365... | Line 358... | ||
365 | 358 | ||
366 | /** |
359 | /** |
367 | * A public function which initializes I/O from/to Serengeti console |
360 | * A public function which initializes I/O from/to Serengeti console |
368 | * and sets it as a default input/output. |
361 | * and sets it as a default input/output. |
369 | */ |
362 | */ |
370 | void sgcn_init(void) |
363 | void sgcn_init(chardev_t *devout) |
371 | { |
364 | { |
372 | sgcn_buffer_begin_init(); |
365 | sgcn_buffer_begin_init(); |
373 | 366 | ||
374 | kbd_type = KBD_SGCN; |
367 | kbd_type = KBD_SGCN; |
375 | 368 | ||
Line 381... | Line 374... | ||
381 | if (!t) |
374 | if (!t) |
382 | panic("Cannot create kkbdpoll."); |
375 | panic("Cannot create kkbdpoll."); |
383 | thread_ready(t); |
376 | thread_ready(t); |
384 | 377 | ||
385 | chardev_initialize("sgcn_io", &sgcn_io, &sgcn_ops); |
378 | chardev_initialize("sgcn_io", &sgcn_io, &sgcn_ops); |
386 | stdin = &sgcn_io; |
- | |
387 | stdout = &sgcn_io; |
379 | stdout = &sgcn_io; |
- | 380 | ||
- | 381 | sgcnout = devout; |
|
388 | } |
382 | } |
389 | 383 | ||
390 | /** @} |
384 | /** @} |
391 | */ |
385 | */ |