source: mainline/kernel/arch/mips32/src/drivers/arc.c@ df4ed85

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

© versus ©

  • Property mode set to 100644
File size: 8.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/** @addtogroup mips32
30 * @{
31 */
32/** @file
33 */
34
35#include <arch/drivers/arc.h>
36#include <arch/mm/page.h>
37#include <print.h>
38#include <arch.h>
39#include <arch/byteorder.h>
40#include <arch/mm/frame.h>
41#include <mm/frame.h>
42#include <interrupt.h>
43#include <align.h>
44#include <console/console.h>
45#include <console/kconsole.h>
46#include <console/cmd.h>
47#include <mm/slab.h>
48
49/* This is a good joke, SGI HAS different types than NT bioses... */
50/* Here is the SGI type */
51static char *basetypes[] = {
52 "ExceptionBlock",
53 "SystemParameterBlock",
54 "FreeContiguous",
55 "FreeMemory",
56 "BadMemory",
57 "LoadedProgram",
58 "FirmwareTemporary",
59 "FirmwarePermanent"
60};
61
62static char *ctypes[] = {
63 "ARC_type",
64 "CPU_type",
65 "FPU_type",
66 "PrimaryICache",
67 "PrimaryDCache",
68 "SecondaryICache",
69 "SecondaryDCache",
70 "SecondaryCache",
71 "Memory",
72 "EISAAdapter",
73 "TCAdapter",
74 "SCSIAdapter",
75 "DTIAdapter",
76 "MultiFunctionAdapter",
77 "DiskController",
78 "TapeController",
79 "CDROMController",
80 "WORMController",
81 "SerialController",
82 "NetworkController",
83 "DisplayController",
84 "ParallelController",
85 "PointerController",
86 "KeyboardController",
87 "AudioController",
88 "OtherController",
89 "DiskPeripheral",
90 "FloppyDiskPeripheral",
91 "TapePeripheral",
92 "ModemPeripheral",
93 "MonitorPeripheral",
94 "PrinterPeripheral",
95 "PointerPeripheral",
96 "KeyboardPeripheral",
97 "TerminalPeripheral",
98 "OtherPeripheral",
99 "LinePeripheral",
100 "NetworkPeripheral"
101 "OtherPeripheral",
102 "XTalkAdapter",
103 "PCIAdapter",
104 "GIOAdapter",
105 "TPUAdapter",
106 "Anonymous"
107};
108
109static arc_sbp *sbp = (arc_sbp *)PA2KA(0x1000);
110static arc_func_vector_t *arc_entry;
111
112
113static void arc_putchar(char ch);
114
115/** Return true if ARC is available */
116int arc_enabled(void)
117{
118 return sbp != NULL;
119}
120
121
122/** Print configuration data that ARC reports about component */
123static void arc_print_confdata(arc_component *c)
124{
125 cm_resource_list *configdata;
126 int i;
127
128 if (!c->configdatasize)
129 return; /* No configuration data */
130
131 configdata = malloc(c->configdatasize, 0);
132
133 if (arc_entry->getconfigurationdata(configdata, c)) {
134 free(configdata);
135 return;
136 }
137 /* Does not seem to return meaningful data, don't use now */
138 free(configdata);
139 return;
140
141 for (i=0; i < configdata->count; i++) {
142 switch (configdata->descr[i].type) {
143 case CmResourceTypePort:
144 printf("Port: %p-size:%d ",
145 (uintptr_t)configdata->descr[i].u.port.start,
146 configdata->descr[i].u.port.length);
147 break;
148 case CmResourceTypeInterrupt:
149 printf("Irq: level(%d) vector(%d) ",
150 configdata->descr[i].u.interrupt.level,
151 configdata->descr[i].u.interrupt.vector);
152 break;
153 case CmResourceTypeMemory:
154 printf("Memory: %p-size:%d ",
155 (uintptr_t)configdata->descr[i].u.port.start,
156 configdata->descr[i].u.port.length);
157 break;
158 default:
159 break;
160 }
161 }
162
163 free(configdata);
164}
165
166/** Print information about component */
167static void arc_print_component(arc_component *c)
168{
169 int i;
170
171 printf("%s: ",ctypes[c->type]);
172 for (i=0;i < c->identifier_len;i++)
173 printf("%c",c->identifier[i]);
174
175 printf(" ");
176 arc_print_confdata(c);
177 printf("\n");
178}
179
180/**
181 * Read from ARC bios configuration data and print it
182 */
183static int cmd_arc_print_devices(cmd_arg_t *argv)
184{
185 arc_component *c,*next;
186
187 c = arc_entry->getchild(NULL);
188 while (c) {
189 arc_print_component(c);
190 next = arc_entry->getchild(c);
191 while (!next) {
192 next = arc_entry->getpeer(c);
193 if (!next)
194 c = arc_entry->getparent(c);
195 if (!c)
196 return 0;
197 }
198 c = next;
199 }
200 return 1;
201}
202static cmd_info_t devlist_info = {
203 .name = "arcdevlist",
204 .description = "Print arc device list",
205 .func = cmd_arc_print_devices,
206 .argc = 0
207};
208
209
210/** Read from arc bios memory map and print it
211 *
212 */
213static int cmd_arc_print_memmap(cmd_arg_t *argv)
214{
215 arc_memdescriptor_t *desc;
216
217 printf("Memory map:\n");
218
219 desc = arc_entry->getmemorydescriptor(NULL);
220 while (desc) {
221 printf("%s: %d(%p) (size: %dKB)\n",basetypes[desc->type],
222 desc->basepage * ARC_FRAME,
223 desc->basepage * ARC_FRAME,
224 desc->basecount*ARC_FRAME/1024);
225 desc = arc_entry->getmemorydescriptor(desc);
226 }
227 return 1;
228}
229static cmd_info_t memmap_info = {
230 .name = "arcmemmap",
231 .description = "Print arc memory map",
232 .func = cmd_arc_print_memmap,
233 .argc = 0
234};
235
236/** Print charactor to console */
237static void arc_putchar(char ch)
238{
239 uint32_t cnt;
240 ipl_t ipl;
241
242 /* TODO: Should be spinlock? */
243 ipl = interrupts_disable();
244 arc_entry->write(1, &ch, 1, &cnt);
245 interrupts_restore(ipl);
246
247}
248
249static int cmd_reboot(cmd_arg_t *argv)
250{
251 arc_entry->reboot();
252 return 0;
253}
254static cmd_info_t reboot_info = {
255 .name = "reboot",
256 .description = "Reboot computer",
257 .func = cmd_reboot,
258 .argc = 0
259};
260
261/** Initialize ARC structure
262 *
263 * @return 0 - ARC OK, -1 - ARC does not exist
264 */
265int arc_init(void)
266{
267 if (sbp->signature != ARC_MAGIC) {
268 sbp = NULL;
269 return -1;
270 }
271 arc_entry = sbp->firmwarevector;
272
273 arc_putchar('A');
274 arc_putchar('R');
275 arc_putchar('C');
276 arc_putchar('\n');
277
278 /* Add command for resetting the computer */
279 cmd_initialize(&reboot_info);
280 cmd_register(&reboot_info);
281 cmd_initialize(&memmap_info);
282 cmd_register(&memmap_info);
283 cmd_initialize(&devlist_info);
284 cmd_register(&devlist_info);
285
286 return 0;
287}
288
289static bool kbd_polling_enabled;
290static chardev_t console;
291
292/** Try to get character, return character or -1 if not available */
293static void arc_keyboard_poll(void)
294{
295 char ch;
296 uint32_t count;
297 long result;
298
299 if (! kbd_polling_enabled)
300 return;
301
302 if (arc_entry->getreadstatus(0))
303 return;
304 result = arc_entry->read(0, &ch, 1, &count);
305 if (result || count!=1) {
306 return;
307 }
308 if (ch == '\r')
309 ch = '\n';
310 if (ch == 0x7f)
311 ch = '\b';
312
313 chardev_push_character(&console, ch);
314}
315
316static char arc_read(chardev_t *dev)
317{
318 char ch;
319 uint32_t count;
320 long result;
321
322 result = arc_entry->read(0, &ch, 1, &count);
323 if (result || count!=1) {
324 printf("Error reading from ARC keyboard.\n");
325 cpu_halt();
326 }
327 if (ch == '\r')
328 return '\n';
329 if (ch == 0x7f)
330 return '\b';
331 return ch;
332}
333
334static void arc_write(chardev_t *dev, const char ch)
335{
336 arc_putchar(ch);
337}
338
339static void arc_enable(chardev_t *dev)
340{
341 kbd_polling_enabled = true;
342}
343
344static void arc_disable(chardev_t *dev)
345{
346 kbd_polling_enabled = false;
347}
348
349static chardev_operations_t arc_ops = {
350 .resume = arc_enable,
351 .suspend = arc_disable,
352 .write = arc_write,
353 .read = arc_read
354};
355
356void arc_console(void)
357{
358 kbd_polling_enabled = true;
359
360 chardev_initialize("arc_console", &console, &arc_ops);
361 virtual_timer_fnc = &arc_keyboard_poll;
362 stdin = &console;
363 stdout = &console;
364}
365
366/* Initialize frame zones from ARC firmware.
367 * In the future we may use even the FirmwareTemporary regions,
368 * currently we use the FreeMemory (what about the LoadedProgram?)
369 */
370void arc_frame_init(void)
371{
372 arc_memdescriptor_t *desc;
373 int total = 0;
374 uintptr_t base;
375 size_t basesize;
376
377 desc = arc_entry->getmemorydescriptor(NULL);
378 while (desc) {
379 if (desc->type == FreeMemory ||
380 desc->type == FreeContiguous) {
381 base = desc->basepage*ARC_FRAME;
382 basesize = desc->basecount*ARC_FRAME;
383
384 if (base % FRAME_SIZE ) {
385 basesize -= FRAME_SIZE - (base % FRAME_SIZE);
386 base = ALIGN_UP(base, FRAME_SIZE);
387 }
388 basesize = ALIGN_DOWN(basesize, FRAME_SIZE);
389
390 total += basesize;
391
392 zone_create(ADDR2PFN(base), SIZE2FRAMES(basesize),
393 ADDR2PFN(base), 0);
394 }
395 desc = arc_entry->getmemorydescriptor(desc);
396 }
397
398 config.memory_size = total;
399}
400
401/** @}
402 */
Note: See TracBrowser for help on using the repository browser.