Subversion Repositories HelenOS

Rev

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