Subversion Repositories HelenOS

Rev

Rev 3618 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3549 rimsky 1
/*
2
 * Copyright (c) 2006 Ondrej Palkovsky
3
 * Copyright (c) 2008 Martin Decky
4
 * Copyright (c) 2008 Pavel Rimsky
5
 * All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 *
11
 * - Redistributions of source code must retain the above copyright
12
 *   notice, this list of conditions and the following disclaimer.
13
 * - Redistributions in binary form must reproduce the above copyright
14
 *   notice, this list of conditions and the following disclaimer in the
15
 *   documentation and/or other materials provided with the distribution.
16
 * - The name of the author may not be used to endorse or promote products
17
 *   derived from this software without specific prior written permission.
18
 *
19
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
 */
30
 
31
/** @defgroup sgcnfb SGCN
32
 * @brief   userland driver of the Serengeti console output
33
 * @{
34
 */
35
/** @file
36
 */
37
 
38
#include <async.h>
39
#include <sysinfo.h>
40
#include <as.h>
41
#include <errno.h>
42
#include <stdio.h>
43
#include <ddi.h>
44
 
3582 rimsky 45
#include "serial_console.h"
3549 rimsky 46
#include "sgcn.h"
47
 
48
#define WIDTH 80
49
#define HEIGHT 24
50
 
51
/**
52
 * Virtual address mapped to SRAM.
53
 */
54
static uintptr_t sram_virt_addr;
55
 
56
/**
57
 * SGCN buffer offset within SGCN.
58
 */
59
static uintptr_t sram_buffer_offset;
60
 
61
/**
62
 * SGCN buffer header. It is placed at the very beginning of the SGCN
63
 * buffer.
64
 */
65
typedef struct {
66
    /** hard-wired to "CON" */
67
    char magic[4];
68
 
69
    /** we don't need this */
3582 rimsky 70
    char unused[24];
3549 rimsky 71
 
72
    /** offset within the SGCN buffer of the output buffer start */
73
    uint32_t out_begin;
74
 
75
    /** offset within the SGCN buffer of the output buffer end */
76
    uint32_t out_end;
77
 
78
    /** offset within the SGCN buffer of the output buffer read pointer */
79
    uint32_t out_rdptr;
80
 
81
    /** offset within the SGCN buffer of the output buffer write pointer */
82
    uint32_t out_wrptr;
83
} __attribute__ ((packed)) sgcn_buffer_header_t;
84
 
85
 
86
/*
87
 * Returns a pointer to the object of a given type which is placed at the given
88
 * offset from the console buffer beginning.
89
 */
90
#define SGCN_BUFFER(type, offset) \
91
        ((type *) (sram_virt_addr + sram_buffer_offset + (offset)))
92
 
93
/** Returns a pointer to the console buffer header. */
94
#define SGCN_BUFFER_HEADER  (SGCN_BUFFER(sgcn_buffer_header_t, 0))
95
 
3618 rimsky 96
/**
97
 * Pushes the character to the SGCN serial.
98
 * @param c character to be pushed
99
 */
3549 rimsky 100
static void sgcn_putc(char c)
101
{
102
    uint32_t begin = SGCN_BUFFER_HEADER->out_begin;
103
    uint32_t end = SGCN_BUFFER_HEADER->out_end;
104
    uint32_t size = end - begin;
105
 
106
    /* we need pointers to volatile variables */
107
    volatile char *buf_ptr = (volatile char *)
108
        SGCN_BUFFER(char, SGCN_BUFFER_HEADER->out_wrptr);
109
    volatile uint32_t *out_wrptr_ptr = &(SGCN_BUFFER_HEADER->out_wrptr);
110
    volatile uint32_t *out_rdptr_ptr = &(SGCN_BUFFER_HEADER->out_rdptr);
111
 
112
    uint32_t new_wrptr = (((*out_wrptr_ptr) - begin + 1) % size) + begin;
113
    while (*out_rdptr_ptr == new_wrptr)
114
        ;
115
    *buf_ptr = c;
116
    *out_wrptr_ptr = new_wrptr;
117
}
118
 
3618 rimsky 119
/**
120
 * Initializes the SGCN serial driver.
121
 */
3549 rimsky 122
int sgcn_init(void)
123
{
3618 rimsky 124
    sram_virt_addr = (uintptr_t) as_get_mappable_page(
125
        sysinfo_value("sram.area.size"));
3549 rimsky 126
    int result = physmem_map(
127
        (void *) sysinfo_value("sram.address.physical"),
128
        (void *) sram_virt_addr,
129
        sysinfo_value("sram.area.size") / PAGE_SIZE,
130
        AS_AREA_READ | AS_AREA_WRITE
131
        );
132
    if (result != 0) {
133
        printf("SGCN: uspace driver couldn't map physical memory: %d\n",
134
            result);
135
    }
136
 
3582 rimsky 137
    serial_console_init(sgcn_putc, WIDTH, HEIGHT);
138
 
3549 rimsky 139
    sram_buffer_offset = sysinfo_value("sram.buffer.offset");
140
 
3742 rimsky 141
    async_set_client_connection(serial_client_connection);
3549 rimsky 142
    return 0;
143
}
144
 
145
/**
146
 * @}
147
 */
3618 rimsky 148