Rev 3502 | Rev 3549 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3502 | Rev 3514 | ||
---|---|---|---|
Line 108... | Line 108... | ||
108 | * Ensures that writing to the buffer and consequent update of the write pointer |
108 | * Ensures that writing to the buffer and consequent update of the write pointer |
109 | * are together one atomic operation. |
109 | * are together one atomic operation. |
110 | */ |
110 | */ |
111 | SPINLOCK_INITIALIZE(sgcn_output_lock); |
111 | SPINLOCK_INITIALIZE(sgcn_output_lock); |
112 | 112 | ||
- | 113 | /* |
|
- | 114 | * Ensures that reading from the buffer and consequent update of the read |
|
- | 115 | * pointer are together one atomic operation. |
|
- | 116 | */ |
|
- | 117 | SPINLOCK_INITIALIZE(sgcn_input_lock); |
|
- | 118 | ||
113 | 119 | ||
- | 120 | /* functions referenced from definitions of I/O operations structures */ |
|
- | 121 | static void sgcn_noop(chardev_t *); |
|
114 | static void sgcn_putchar(struct chardev * cd, const char c); |
122 | static void sgcn_putchar(chardev_t *, const char); |
- | 123 | static char sgcn_key_read(chardev_t *); |
|
115 | 124 | ||
116 | /** character device operations */ |
125 | /** character device output operations */ |
117 | static chardev_operations_t sgcn_ops = { |
126 | static chardev_operations_t sgcn_output_ops = { |
118 | .suspend = NULL, |
127 | .suspend = sgcn_noop, |
119 | .resume = NULL, |
128 | .resume = sgcn_noop, |
120 | .write = sgcn_putchar, |
129 | .write = sgcn_putchar, |
121 | .read = NULL |
130 | .read = NULL |
122 | }; |
131 | }; |
123 | 132 | ||
- | 133 | /** character device input operations */ |
|
- | 134 | static chardev_operations_t sgcn_input_ops = { |
|
- | 135 | .suspend = sgcn_noop, |
|
- | 136 | .resume = sgcn_noop, |
|
- | 137 | .read = sgcn_key_read |
|
- | 138 | }; |
|
- | 139 | ||
- | 140 | ||
124 | /** SGCN character device */ |
141 | /** SGCN character output device */ |
125 | chardev_t sgcn_stdout; |
142 | chardev_t sgcn_stdout; |
126 | 143 | ||
- | 144 | /** SGCN character input device */ |
|
- | 145 | chardev_t sgcn_input; |
|
- | 146 | ||
- | 147 | ||
127 | /** |
148 | /** |
128 | * Initializes the starting address of SRAM. |
149 | * Initializes the starting address of SRAM. |
129 | * |
150 | * |
130 | * The SRAM starts 0x900000 + C bytes behind the SBBC start in the |
151 | * The SRAM starts 0x900000 + C bytes behind the SBBC start in the |
131 | * physical memory, where C is the value read from the "iosram-toc" |
152 | * physical memory, where C is the value read from the "iosram-toc" |
Line 178... | Line 199... | ||
178 | 199 | ||
179 | sgcn_buffer_begin = sram_begin + SRAM_TOC->keys[i].offset; |
200 | sgcn_buffer_begin = sram_begin + SRAM_TOC->keys[i].offset; |
180 | } |
201 | } |
181 | 202 | ||
182 | /** |
203 | /** |
- | 204 | * Default suspend/resume operation for the input device. |
|
- | 205 | */ |
|
- | 206 | static void sgcn_noop(chardev_t *d) |
|
- | 207 | { |
|
- | 208 | } |
|
- | 209 | ||
- | 210 | /** |
|
183 | * Writes a single character to the SGCN (circular) output buffer |
211 | * Writes a single character to the SGCN (circular) output buffer |
184 | * and updates the output write pointer so that SGCN gets to know |
212 | * and updates the output write pointer so that SGCN gets to know |
185 | * that the character has been written. |
213 | * that the character has been written. |
186 | */ |
214 | */ |
187 | static void sgcn_do_putchar(const char c) |
215 | static void sgcn_do_putchar(const char c) |
Line 233... | Line 261... | ||
233 | 261 | ||
234 | spinlock_unlock(&sgcn_output_lock); |
262 | spinlock_unlock(&sgcn_output_lock); |
235 | } |
263 | } |
236 | 264 | ||
237 | /** |
265 | /** |
- | 266 | * Called when actively reading the character. Not implemented yet. |
|
- | 267 | */ |
|
- | 268 | static char sgcn_key_read(chardev_t *d) |
|
- | 269 | { |
|
- | 270 | return (char) 0; |
|
- | 271 | } |
|
- | 272 | ||
- | 273 | /** |
|
- | 274 | * Function regularly called by the keyboard polling thread. Finds out whether |
|
- | 275 | * there are some unread characters in the input queue. If so, it picks them up |
|
- | 276 | * and sends them to the upper layers of HelenOS. |
|
- | 277 | */ |
|
- | 278 | void sgcn_poll(void) |
|
- | 279 | { |
|
- | 280 | spinlock_lock(&sgcn_input_lock); |
|
- | 281 | ||
- | 282 | char c; |
|
- | 283 | uint32_t begin = SGCN_BUFFER_HEADER->in_begin; |
|
- | 284 | uint32_t end = SGCN_BUFFER_HEADER->in_end; |
|
- | 285 | uint32_t size = end - begin; |
|
- | 286 | ||
- | 287 | /* we need pointers to volatile variables */ |
|
- | 288 | volatile char *buf_ptr = (volatile char *) |
|
- | 289 | SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr); |
|
- | 290 | volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr); |
|
- | 291 | volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr); |
|
- | 292 | ||
- | 293 | while (*in_rdptr_ptr != *in_wrptr_ptr) { |
|
- | 294 | c = *buf_ptr; |
|
- | 295 | *in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin; |
|
- | 296 | buf_ptr = (volatile char *) |
|
- | 297 | SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr); |
|
- | 298 | chardev_push_character(&sgcn_input, c); |
|
- | 299 | if (c == '\r') |
|
- | 300 | chardev_push_character(&sgcn_input, '\n'); |
|
- | 301 | } |
|
- | 302 | ||
- | 303 | spinlock_unlock(&sgcn_input_lock); |
|
- | 304 | } |
|
- | 305 | ||
- | 306 | /** |
|
238 | * A public function which initializes I/O from/to Serengeti console |
307 | * A public function which initializes I/O from/to Serengeti console |
239 | * and sets it as a default input/output. |
308 | * and sets it as a default input/output. |
240 | */ |
309 | */ |
241 | void sgcn_init(void) |
310 | void sgcn_init(void) |
242 | { |
311 | { |
243 | sgcn_buffer_begin_init(); |
312 | sgcn_buffer_begin_init(); |
244 | 313 | ||
245 | chardev_initialize("sgcn_output", &sgcn_stdout, &sgcn_ops); |
314 | chardev_initialize("sgcn_output", &sgcn_stdout, &sgcn_output_ops); |
246 | stdout = &sgcn_stdout; |
315 | stdout = &sgcn_stdout; |
247 | 316 | ||
248 | - | ||
249 | printf("SGCN buffer begin = %d, in read ptr = %" PRIu32 ".", sgcn_buffer_begin, SGCN_BUFFER_HEADER->in_wrptr); |
317 | chardev_initialize("sgcn_input", &sgcn_input, &sgcn_input_ops); |
- | 318 | stdin = &sgcn_input; |
|
250 | } |
319 | } |
251 | 320 | ||
252 | /** @} |
321 | /** @} |
253 | */ |
322 | */ |
254 | 323 |