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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since daea4bf was daea4bf, checked in by Ondrej Palkovsky <ondrap@…>, 19 years ago

Some arc bios tweaks. Wanted to print configuration data, but
the ARC seems to return strange values.
Newport graphics card does not seem to be easy to port, give up now.

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