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 | */ |