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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 7208b6c 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
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
113/** Return true if ARC is available */
114#define arc_enabled() (sbp != NULL)
115
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
136 for (i = 0; i < configdata->count; i++) {
137 switch (configdata->descr[i].type) {
138 case CmResourceTypePort:
139 printf("Port: %p-size:%d ",
140 (uintptr_t) configdata->descr[i].u.port.start,
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:
149 printf("Memory: %p-size:%d ",
150 (uintptr_t)configdata->descr[i].u.port.start,
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 */
162static void arc_print_component(arc_component *c)
163{
164 int i;
165
166 printf("%s: ",ctypes[c->type]);
167 for (i = 0; i < c->identifier_len; i++)
168 printf("%c", c->identifier[i]);
169
170 printf(" ");
171 arc_print_confdata(c);
172 printf("\n");
173}
174
175/**
176 * Read from ARC bios configuration data and print it
177 */
178static int cmd_arc_print_devices(cmd_arg_t *argv)
179{
180 arc_component *c, *next;
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)
191 return 0;
192 }
193 c = next;
194 }
195 return 1;
196}
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};
203
204
205/** Read from arc bios memory map and print it
206 *
207 */
208void physmem_print(void)
209{
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
223 printf("%#10x %#10x free\n", 0, CONFIG_MEMORY_SIZE);
224}
225
226/** Print charactor to console */
227static void arc_putchar(char ch)
228{
229 uint32_t cnt;
230 ipl_t ipl;
231
232 /* TODO: Should be spinlock? */
233 ipl = interrupts_disable();
234 arc_entry->write(1, &ch, 1, &cnt);
235 interrupts_restore(ipl);
236}
237
238
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');
255
256 /* Add command for resetting the computer */
257 cmd_initialize(&devlist_info);
258 cmd_register(&devlist_info);
259
260 return 0;
261}
262
263int arc_reboot(void)
264{
265 if (arc_enabled()) {
266 arc_entry->reboot();
267 return true;
268 }
269
270 return false;
271}
272
273
274static bool kbd_polling_enabled;
275static chardev_t console;
276
277/** Try to get character, return character or -1 if not available */
278static void arc_keyboard_poll(void)
279{
280 char ch;
281 uint32_t count;
282 long result;
283
284 if (!kbd_polling_enabled)
285 return;
286
287 if (arc_entry->getreadstatus(0))
288 return;
289 result = arc_entry->read(0, &ch, 1, &count);
290 if ((result) || (count != 1)) {
291 return;
292 }
293 if (ch == '\r')
294 ch = '\n';
295 if (ch == 0x7f)
296 ch = '\b';
297
298 chardev_push_character(&console, ch);
299}
300
301static char arc_read(chardev_t *dev)
302{
303 char ch;
304 uint32_t count;
305 long result;
306
307 result = arc_entry->read(0, &ch, 1, &count);
308 if ((result) || (count != 1)) {
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
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{
326 kbd_polling_enabled = true;
327}
328
329static void arc_disable(chardev_t *dev)
330{
331 kbd_polling_enabled = false;
332}
333
334static chardev_operations_t arc_ops = {
335 .resume = arc_enable,
336 .suspend = arc_disable,
337 .write = arc_write,
338 .read = arc_read
339};
340
341int arc_console(void)
342{
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 }
353
354 return false;
355}
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 */
361int arc_frame_init(void)
362{
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);
383 }
384 desc = arc_entry->getmemorydescriptor(desc);
385 }
386
387 return true;
388 }
389
390 return false;
391}
392
393/** @}
394 */
Note: See TracBrowser for help on using the repository browser.