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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 71eef11 was 71eef11, checked in by Martin Decky <martin@…>, 17 years ago

remove config.memory_size, get_memory_size() and memory_init.{c|d}
the amount of available memory can be calculated from the sizes of the zones
add FRAMES2SIZE, SIZE2KB and SIZE2MB functions/macros (code readability)

  • Property mode set to 100644
File size: 8.4 KB
RevLine 
[3156582]1/*
[df4ed85]2 * Copyright (c) 2005 Ondrej Palkovsky
[3156582]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
[06e1e95]29/** @addtogroup mips32
[b45c443]30 * @{
31 */
32/** @file
33 */
34
[3156582]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>
[939dfd7]40#include <arch/mm/frame.h>
41#include <mm/frame.h>
[973be64e]42#include <interrupt.h>
[c0b7f00]43#include <align.h>
[af9a7c5]44#include <console/console.h>
[052da81]45#include <console/kconsole.h>
46#include <console/cmd.h>
[daea4bf]47#include <mm/slab.h>
[3156582]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
[c7a7656]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
[b5ed4f8]109static arc_sbp *sbp = (arc_sbp *) PA2KA(0x1000);
[3156582]110static arc_func_vector_t *arc_entry;
111
112
113/** Return true if ARC is available */
[b5ed4f8]114#define arc_enabled() (sbp != NULL)
[3156582]115
[daea4bf]116
117/** Print configuration data that ARC reports about component */
118static void arc_print_confdata(arc_component *c)
119{
120 cm_resource_list *configdata;
121 int i;
122
123 if (!c->configdatasize)
124 return; /* No configuration data */
125
126 configdata = malloc(c->configdatasize, 0);
127
128 if (arc_entry->getconfigurationdata(configdata, c)) {
129 free(configdata);
130 return;
131 }
132 /* Does not seem to return meaningful data, don't use now */
133 free(configdata);
134 return;
135
[b5ed4f8]136 for (i = 0; i < configdata->count; i++) {
[daea4bf]137 switch (configdata->descr[i].type) {
138 case CmResourceTypePort:
[cf85e24c]139 printf("Port: %p-size:%d ",
[b5ed4f8]140 (uintptr_t) configdata->descr[i].u.port.start,
[daea4bf]141 configdata->descr[i].u.port.length);
142 break;
143 case CmResourceTypeInterrupt:
144 printf("Irq: level(%d) vector(%d) ",
145 configdata->descr[i].u.interrupt.level,
146 configdata->descr[i].u.interrupt.vector);
147 break;
148 case CmResourceTypeMemory:
[cf85e24c]149 printf("Memory: %p-size:%d ",
[7f1c620]150 (uintptr_t)configdata->descr[i].u.port.start,
[daea4bf]151 configdata->descr[i].u.port.length);
152 break;
153 default:
154 break;
155 }
156 }
157
158 free(configdata);
159}
160
161/** Print information about component */
[c7a7656]162static void arc_print_component(arc_component *c)
163{
164 int i;
165
166 printf("%s: ",ctypes[c->type]);
[b5ed4f8]167 for (i = 0; i < c->identifier_len; i++)
168 printf("%c", c->identifier[i]);
[daea4bf]169
170 printf(" ");
171 arc_print_confdata(c);
172 printf("\n");
[c7a7656]173}
174
[daea4bf]175/**
176 * Read from ARC bios configuration data and print it
177 */
178static int cmd_arc_print_devices(cmd_arg_t *argv)
[c7a7656]179{
[b5ed4f8]180 arc_component *c, *next;
[c7a7656]181
182 c = arc_entry->getchild(NULL);
183 while (c) {
184 arc_print_component(c);
185 next = arc_entry->getchild(c);
186 while (!next) {
187 next = arc_entry->getpeer(c);
188 if (!next)
189 c = arc_entry->getparent(c);
190 if (!c)
[daea4bf]191 return 0;
[c7a7656]192 }
193 c = next;
194 }
[daea4bf]195 return 1;
[c7a7656]196}
[daea4bf]197static cmd_info_t devlist_info = {
198 .name = "arcdevlist",
199 .description = "Print arc device list",
200 .func = cmd_arc_print_devices,
201 .argc = 0
202};
[c7a7656]203
[daea4bf]204
205/** Read from arc bios memory map and print it
206 *
207 */
[b5ed4f8]208void physmem_print(void)
[3156582]209{
[b5ed4f8]210 printf("Base Size Type\n");
211 printf("---------- ---------- ---------\n");
212
213 if (arc_enabled()) {
214 arc_memdescriptor_t *desc = arc_entry->getmemorydescriptor(NULL);
215
216 while (desc) {
217 printf("%#10x %#10x %s\n",
218 desc->basepage * ARC_FRAME, desc->basecount * ARC_FRAME,
219 basetypes[desc->type]);
220 desc = arc_entry->getmemorydescriptor(desc);
221 }
222 } else
[71eef11]223 printf("%#10x %#10x free\n", 0, CONFIG_MEMORY_SIZE);
[3156582]224}
225
226/** Print charactor to console */
[973be64e]227static void arc_putchar(char ch)
[3156582]228{
[7f1c620]229 uint32_t cnt;
[22f7769]230 ipl_t ipl;
[3156582]231
232 /* TODO: Should be spinlock? */
[22f7769]233 ipl = interrupts_disable();
[3156582]234 arc_entry->write(1, &ch, 1, &cnt);
[22f7769]235 interrupts_restore(ipl);
[3156582]236}
[ac0cb2a]237
[052da81]238
[973be64e]239/** Initialize ARC structure
240 *
241 * @return 0 - ARC OK, -1 - ARC does not exist
242 */
243int arc_init(void)
244{
245 if (sbp->signature != ARC_MAGIC) {
246 sbp = NULL;
247 return -1;
248 }
249 arc_entry = sbp->firmwarevector;
250
251 arc_putchar('A');
252 arc_putchar('R');
253 arc_putchar('C');
254 arc_putchar('\n');
[80d2bdb]255
[052da81]256 /* Add command for resetting the computer */
[daea4bf]257 cmd_initialize(&devlist_info);
258 cmd_register(&devlist_info);
[052da81]259
[80d2bdb]260 return 0;
[973be64e]261}
262
[b5ed4f8]263int arc_reboot(void)
264{
265 if (arc_enabled()) {
266 arc_entry->reboot();
267 return true;
268 }
269
270 return false;
271}
272
273
[6095342]274static bool kbd_polling_enabled;
[973be64e]275static chardev_t console;
276
[ac0cb2a]277/** Try to get character, return character or -1 if not available */
[973be64e]278static void arc_keyboard_poll(void)
[ac0cb2a]279{
280 char ch;
[7f1c620]281 uint32_t count;
[ac0cb2a]282 long result;
[973be64e]283
[b5ed4f8]284 if (!kbd_polling_enabled)
[973be64e]285 return;
[ac0cb2a]286
287 if (arc_entry->getreadstatus(0))
[973be64e]288 return;
[ac0cb2a]289 result = arc_entry->read(0, &ch, 1, &count);
[b5ed4f8]290 if ((result) || (count != 1)) {
[973be64e]291 return;
[ac0cb2a]292 }
293 if (ch == '\r')
[973be64e]294 ch = '\n';
[e8a9dc3]295 if (ch == 0x7f)
296 ch = '\b';
297
[973be64e]298 chardev_push_character(&console, ch);
299}
300
[fbe058f]301static char arc_read(chardev_t *dev)
302{
303 char ch;
[7f1c620]304 uint32_t count;
[fbe058f]305 long result;
306
307 result = arc_entry->read(0, &ch, 1, &count);
[b5ed4f8]308 if ((result) || (count != 1)) {
[fbe058f]309 printf("Error reading from ARC keyboard.\n");
310 cpu_halt();
311 }
312 if (ch == '\r')
313 return '\n';
314 if (ch == 0x7f)
315 return '\b';
316 return ch;
317}
318
[973be64e]319static void arc_write(chardev_t *dev, const char ch)
320{
321 arc_putchar(ch);
322}
323
324static void arc_enable(chardev_t *dev)
325{
[6095342]326 kbd_polling_enabled = true;
[973be64e]327}
328
329static void arc_disable(chardev_t *dev)
330{
[6095342]331 kbd_polling_enabled = false;
[973be64e]332}
333
334static chardev_operations_t arc_ops = {
335 .resume = arc_enable,
336 .suspend = arc_disable,
[fbe058f]337 .write = arc_write,
338 .read = arc_read
[973be64e]339};
340
[b5ed4f8]341int arc_console(void)
[973be64e]342{
[b5ed4f8]343 if (arc_enabled()) {
344 kbd_polling_enabled = true;
345
346 chardev_initialize("arc_console", &console, &arc_ops);
347 virtual_timer_fnc = &arc_keyboard_poll;
348 stdin = &console;
349 stdout = &console;
350
351 return true;
352 }
[973be64e]353
[b5ed4f8]354 return false;
[ac0cb2a]355}
[939dfd7]356
357/* Initialize frame zones from ARC firmware.
358 * In the future we may use even the FirmwareTemporary regions,
359 * currently we use the FreeMemory (what about the LoadedProgram?)
360 */
[b5ed4f8]361int arc_frame_init(void)
[939dfd7]362{
[b5ed4f8]363 if (arc_enabled()) {
364 arc_memdescriptor_t *desc;
365 uintptr_t base;
366 size_t basesize;
367
368 desc = arc_entry->getmemorydescriptor(NULL);
369 while (desc) {
370 if ((desc->type == FreeMemory) ||
371 (desc->type == FreeContiguous)) {
372 base = desc->basepage*ARC_FRAME;
373 basesize = desc->basecount*ARC_FRAME;
374
375 if (base % FRAME_SIZE ) {
376 basesize -= FRAME_SIZE - (base % FRAME_SIZE);
377 base = ALIGN_UP(base, FRAME_SIZE);
378 }
379 basesize = ALIGN_DOWN(basesize, FRAME_SIZE);
380
381 zone_create(ADDR2PFN(base), SIZE2FRAMES(basesize),
382 ADDR2PFN(base), 0);
[c0b7f00]383 }
[b5ed4f8]384 desc = arc_entry->getmemorydescriptor(desc);
[939dfd7]385 }
[b5ed4f8]386
387 return true;
[939dfd7]388 }
[b5ed4f8]389
390 return false;
[939dfd7]391}
392
[06e1e95]393/** @}
[b45c443]394 */
Note: See TracBrowser for help on using the repository browser.