source: mainline/arch/mips32/src/drivers/arc.c@ 85dc2e7

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

Convert size_t, count_t and index_t to 64-bits on 64-bit architectures.
Change some pfn_t usages to count_t, size_t and index_t.

  • Property mode set to 100644
File size: 6.7 KB
Line 
1/*
2 * Copyright (C) 2005 Ondrej Palkovsky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <arch/drivers/arc.h>
30#include <arch/mm/page.h>
31#include <print.h>
32#include <arch.h>
33#include <arch/byteorder.h>
34#include <arch/mm/frame.h>
35#include <mm/frame.h>
36#include <interrupt.h>
37#include <align.h>
38#include <console/console.h>
39
40/* This is a good joke, SGI HAS different types than NT bioses... */
41/* Here is the SGI type */
42static char *basetypes[] = {
43 "ExceptionBlock",
44 "SystemParameterBlock",
45 "FreeContiguous",
46 "FreeMemory",
47 "BadMemory",
48 "LoadedProgram",
49 "FirmwareTemporary",
50 "FirmwarePermanent"
51};
52
53static char *ctypes[] = {
54 "ARC_type",
55 "CPU_type",
56 "FPU_type",
57 "PrimaryICache",
58 "PrimaryDCache",
59 "SecondaryICache",
60 "SecondaryDCache",
61 "SecondaryCache",
62 "Memory",
63 "EISAAdapter",
64 "TCAdapter",
65 "SCSIAdapter",
66 "DTIAdapter",
67 "MultiFunctionAdapter",
68 "DiskController",
69 "TapeController",
70 "CDROMController",
71 "WORMController",
72 "SerialController",
73 "NetworkController",
74 "DisplayController",
75 "ParallelController",
76 "PointerController",
77 "KeyboardController",
78 "AudioController",
79 "OtherController",
80 "DiskPeripheral",
81 "FloppyDiskPeripheral",
82 "TapePeripheral",
83 "ModemPeripheral",
84 "MonitorPeripheral",
85 "PrinterPeripheral",
86 "PointerPeripheral",
87 "KeyboardPeripheral",
88 "TerminalPeripheral",
89 "OtherPeripheral",
90 "LinePeripheral",
91 "NetworkPeripheral"
92 "OtherPeripheral",
93 "XTalkAdapter",
94 "PCIAdapter",
95 "GIOAdapter",
96 "TPUAdapter",
97 "Anonymous"
98};
99
100static arc_sbp *sbp = (arc_sbp *)PA2KA(0x1000);
101static arc_func_vector_t *arc_entry;
102
103
104static void arc_putchar(char ch);
105
106/** Return true if ARC is available */
107int arc_enabled(void)
108{
109 return sbp != NULL;
110}
111
112static void arc_print_component(arc_component *c)
113{
114 int i;
115
116 printf("%s: ",ctypes[c->type]);
117 for (i=0;i < c->identifier_len;i++)
118 arc_putchar(c->identifier[i]);
119 arc_putchar('\n');
120}
121
122void arc_print_devices(void)
123{
124 arc_component *c,*next;
125
126 if (!arc_enabled())
127 return;
128
129 c = arc_entry->getchild(NULL);
130 while (c) {
131 arc_print_component(c);
132 next = arc_entry->getchild(c);
133 while (!next) {
134 next = arc_entry->getpeer(c);
135 if (!next)
136 c = arc_entry->getparent(c);
137 if (!c)
138 return;
139 }
140 c = next;
141 }
142}
143
144void arc_print_memory_map(void)
145{
146 arc_memdescriptor_t *desc;
147
148 if (!arc_enabled())
149 return;
150
151 printf("Memory map:\n");
152
153 desc = arc_entry->getmemorydescriptor(NULL);
154 while (desc) {
155 printf("%s: %d (size: %dKB)\n",basetypes[desc->type],
156 desc->basepage * ARC_FRAME,
157 desc->basecount*ARC_FRAME/1024);
158 desc = arc_entry->getmemorydescriptor(desc);
159 }
160}
161
162/** Print charactor to console */
163static void arc_putchar(char ch)
164{
165 __u32 cnt;
166 ipl_t ipl;
167
168 /* TODO: Should be spinlock? */
169 ipl = interrupts_disable();
170 arc_entry->write(1, &ch, 1, &cnt);
171 interrupts_restore(ipl);
172
173}
174
175/** Initialize ARC structure
176 *
177 * @return 0 - ARC OK, -1 - ARC does not exist
178 */
179int arc_init(void)
180{
181 if (sbp->signature != ARC_MAGIC) {
182 sbp = NULL;
183 return -1;
184 }
185 arc_entry = sbp->firmwarevector;
186
187 arc_putchar('A');
188 arc_putchar('R');
189 arc_putchar('C');
190 arc_putchar('\n');
191
192 return 0;
193}
194
195static bool kbd_polling_enabled;
196static chardev_t console;
197
198/** Try to get character, return character or -1 if not available */
199static void arc_keyboard_poll(void)
200{
201 char ch;
202 __u32 count;
203 long result;
204
205 if (! kbd_polling_enabled)
206 return;
207
208 if (arc_entry->getreadstatus(0))
209 return;
210 result = arc_entry->read(0, &ch, 1, &count);
211 if (result || count!=1) {
212 return;
213 }
214 if (ch == '\r')
215 ch = '\n';
216 if (ch == 0x7f)
217 ch = '\b';
218
219 chardev_push_character(&console, ch);
220}
221
222static char arc_read(chardev_t *dev)
223{
224 char ch;
225 __u32 count;
226 long result;
227
228 result = arc_entry->read(0, &ch, 1, &count);
229 if (result || count!=1) {
230 printf("Error reading from ARC keyboard.\n");
231 cpu_halt();
232 }
233 if (ch == '\r')
234 return '\n';
235 if (ch == 0x7f)
236 return '\b';
237 return ch;
238}
239
240static void arc_write(chardev_t *dev, const char ch)
241{
242 arc_putchar(ch);
243}
244
245static void arc_enable(chardev_t *dev)
246{
247 kbd_polling_enabled = true;
248}
249
250static void arc_disable(chardev_t *dev)
251{
252 kbd_polling_enabled = false;
253}
254
255static chardev_operations_t arc_ops = {
256 .resume = arc_enable,
257 .suspend = arc_disable,
258 .write = arc_write,
259 .read = arc_read
260};
261
262iroutine old_timer;
263/** Do polling on timer interrupt */
264static void timer_replace(int n, void *stack)
265{
266 arc_keyboard_poll();
267 old_timer(n, stack);
268 arc_keyboard_poll();
269}
270
271void arc_console(void)
272{
273 kbd_polling_enabled = true;
274
275 chardev_initialize("arc_console", &console, &arc_ops);
276 old_timer = int_register(TIMER_IRQ, "arc_kb_poll", timer_replace);
277 stdin = &console;
278 stdout = &console;
279}
280
281/* Initialize frame zones from ARC firmware.
282 * In the future we may use even the FirmwareTemporary regions,
283 * currently we use the FreeMemory (what about the LoadedProgram?)
284 */
285void arc_frame_init(void)
286{
287 arc_memdescriptor_t *desc;
288 int total = 0;
289 __address base;
290 size_t basesize;
291
292 desc = arc_entry->getmemorydescriptor(NULL);
293 while (desc) {
294 if (desc->type == FreeMemory ||
295 desc->type == FreeContiguous) {
296 base = desc->basepage*ARC_FRAME;
297 basesize = desc->basecount*ARC_FRAME;
298
299 if (base % FRAME_SIZE ) {
300 basesize -= FRAME_SIZE - (base % FRAME_SIZE);
301 base = ALIGN_UP(base, FRAME_SIZE);
302 }
303 basesize = ALIGN_DOWN(basesize, FRAME_SIZE);
304
305 total += basesize;
306
307 zone_create(ADDR2PFN(base),
308 SIZE2FRAMES(ALIGN_DOWN(basesize,FRAME_SIZE)),
309 ADDR2PFN(base),0);
310 }
311 desc = arc_entry->getmemorydescriptor(desc);
312 }
313
314 config.memory_size = total;
315}
316
Note: See TracBrowser for help on using the repository browser.