source: mainline/uspace/srv/fb/sgcn.c@ 965dc18

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 965dc18 was 965dc18, checked in by Jakub Jermar <jakub@…>, 17 years ago

Merge sparc branch to trunk.

  • Property mode set to 100644
File size: 6.2 KB
Line 
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 <ipc/ipc.h>
40#include <ipc/fb.h>
41#include <sysinfo.h>
42#include <as.h>
43#include <errno.h>
44#include <stdio.h>
45#include <ddi.h>
46
47#include "serial_console.h"
48#include "sgcn.h"
49
50#define WIDTH 80
51#define HEIGHT 24
52
53/**
54 * Virtual address mapped to SRAM.
55 */
56static uintptr_t sram_virt_addr;
57
58/**
59 * SGCN buffer offset within SGCN.
60 */
61static uintptr_t sram_buffer_offset;
62
63/* Allow only 1 connection */
64static int client_connected = 0;
65
66/**
67 * SGCN buffer header. It is placed at the very beginning of the SGCN
68 * buffer.
69 */
70typedef struct {
71 /** hard-wired to "CON" */
72 char magic[4];
73
74 /** we don't need this */
75 char unused[24];
76
77 /** offset within the SGCN buffer of the output buffer start */
78 uint32_t out_begin;
79
80 /** offset within the SGCN buffer of the output buffer end */
81 uint32_t out_end;
82
83 /** offset within the SGCN buffer of the output buffer read pointer */
84 uint32_t out_rdptr;
85
86 /** offset within the SGCN buffer of the output buffer write pointer */
87 uint32_t out_wrptr;
88} __attribute__ ((packed)) sgcn_buffer_header_t;
89
90
91/*
92 * Returns a pointer to the object of a given type which is placed at the given
93 * offset from the console buffer beginning.
94 */
95#define SGCN_BUFFER(type, offset) \
96 ((type *) (sram_virt_addr + sram_buffer_offset + (offset)))
97
98/** Returns a pointer to the console buffer header. */
99#define SGCN_BUFFER_HEADER (SGCN_BUFFER(sgcn_buffer_header_t, 0))
100
101/**
102 * Pushes the character to the SGCN serial.
103 * @param c character to be pushed
104 */
105static void sgcn_putc(char c)
106{
107 uint32_t begin = SGCN_BUFFER_HEADER->out_begin;
108 uint32_t end = SGCN_BUFFER_HEADER->out_end;
109 uint32_t size = end - begin;
110
111 /* we need pointers to volatile variables */
112 volatile char *buf_ptr = (volatile char *)
113 SGCN_BUFFER(char, SGCN_BUFFER_HEADER->out_wrptr);
114 volatile uint32_t *out_wrptr_ptr = &(SGCN_BUFFER_HEADER->out_wrptr);
115 volatile uint32_t *out_rdptr_ptr = &(SGCN_BUFFER_HEADER->out_rdptr);
116
117 uint32_t new_wrptr = (((*out_wrptr_ptr) - begin + 1) % size) + begin;
118 while (*out_rdptr_ptr == new_wrptr)
119 ;
120 *buf_ptr = c;
121 *out_wrptr_ptr = new_wrptr;
122}
123
124/**
125 * Main function of the thread serving client connections.
126 */
127static void sgcn_client_connection(ipc_callid_t iid, ipc_call_t *icall)
128{
129 int retval;
130 ipc_callid_t callid;
131 ipc_call_t call;
132 char c;
133 int lastcol = 0;
134 int lastrow = 0;
135 int newcol;
136 int newrow;
137 int fgcolor;
138 int bgcolor;
139 int i;
140
141 if (client_connected) {
142 ipc_answer_0(iid, ELIMIT);
143 return;
144 }
145
146 client_connected = 1;
147 ipc_answer_0(iid, EOK);
148
149 /* Clear the terminal, set scrolling region
150 to 0 - 24 lines */
151 serial_clrscr();
152 serial_goto(0, 0);
153 serial_puts("\033[0;24r");
154
155 while (true) {
156 callid = async_get_call(&call);
157 switch (IPC_GET_METHOD(call)) {
158 case IPC_M_PHONE_HUNGUP:
159 client_connected = 0;
160 ipc_answer_0(callid, EOK);
161 return;
162 case FB_PUTCHAR:
163 c = IPC_GET_ARG1(call);
164 newrow = IPC_GET_ARG2(call);
165 newcol = IPC_GET_ARG3(call);
166 if ((lastcol != newcol) || (lastrow != newrow))
167 serial_goto(newrow, newcol);
168 lastcol = newcol + 1;
169 lastrow = newrow;
170 sgcn_putc(c);
171 retval = 0;
172 break;
173 case FB_CURSOR_GOTO:
174 newrow = IPC_GET_ARG1(call);
175 newcol = IPC_GET_ARG2(call);
176 serial_goto(newrow, newcol);
177 lastrow = newrow;
178 lastcol = newcol;
179 retval = 0;
180 break;
181 case FB_GET_CSIZE:
182 ipc_answer_2(callid, EOK, HEIGHT, WIDTH);
183 continue;
184 case FB_CLEAR:
185 serial_clrscr();
186 retval = 0;
187 break;
188 case FB_SET_STYLE:
189 fgcolor = IPC_GET_ARG1(call);
190 bgcolor = IPC_GET_ARG2(call);
191 if (fgcolor < bgcolor)
192 serial_set_style(0);
193 else
194 serial_set_style(7);
195 retval = 0;
196 break;
197 case FB_SCROLL:
198 i = IPC_GET_ARG1(call);
199 if ((i > HEIGHT) || (i < -HEIGHT)) {
200 retval = EINVAL;
201 break;
202 }
203 serial_scroll(i);
204 serial_goto(lastrow, lastcol);
205 retval = 0;
206 break;
207 case FB_CURSOR_VISIBILITY:
208 if(IPC_GET_ARG1(call))
209 serial_cursor_enable();
210 else
211 serial_cursor_disable();
212 retval = 0;
213 break;
214 default:
215 retval = ENOENT;
216 }
217 ipc_answer_0(callid, retval);
218 }
219}
220
221/**
222 * Initializes the SGCN serial driver.
223 */
224int sgcn_init(void)
225{
226 sram_virt_addr = (uintptr_t) as_get_mappable_page(
227 sysinfo_value("sram.area.size"));
228 int result = physmem_map(
229 (void *) sysinfo_value("sram.address.physical"),
230 (void *) sram_virt_addr,
231 sysinfo_value("sram.area.size") / PAGE_SIZE,
232 AS_AREA_READ | AS_AREA_WRITE
233 );
234 if (result != 0) {
235 printf("SGCN: uspace driver couldn't map physical memory: %d\n",
236 result);
237 }
238
239 serial_console_init(sgcn_putc, WIDTH, HEIGHT);
240
241 sram_buffer_offset = sysinfo_value("sram.buffer.offset");
242
243 async_set_client_connection(sgcn_client_connection);
244 return 0;
245}
246
247/**
248 * @}
249 */
250
Note: See TracBrowser for help on using the repository browser.