OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [powerpc/] [boot/] [oflib.c] - Blame information for rev 17

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 * Copyright (C) Paul Mackerras 1997.
3
 *
4
 * This program is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU General Public License
6
 * as published by the Free Software Foundation; either version
7
 * 2 of the License, or (at your option) any later version.
8
 */
9
#include <stddef.h>
10
#include "types.h"
11
#include "elf.h"
12
#include "string.h"
13
#include "stdio.h"
14
#include "page.h"
15
#include "ops.h"
16
 
17
#include "of.h"
18
 
19
static int (*prom) (void *);
20
 
21
void of_init(void *promptr)
22
{
23
        prom = (int (*)(void *))promptr;
24
}
25
 
26
int of_call_prom(const char *service, int nargs, int nret, ...)
27
{
28
        int i;
29
        struct prom_args {
30
                const char *service;
31
                int nargs;
32
                int nret;
33
                unsigned int args[12];
34
        } args;
35
        va_list list;
36
 
37
        args.service = service;
38
        args.nargs = nargs;
39
        args.nret = nret;
40
 
41
        va_start(list, nret);
42
        for (i = 0; i < nargs; i++)
43
                args.args[i] = va_arg(list, unsigned int);
44
        va_end(list);
45
 
46
        for (i = 0; i < nret; i++)
47
                args.args[nargs+i] = 0;
48
 
49
        if (prom(&args) < 0)
50
                return -1;
51
 
52
        return (nret > 0)? args.args[nargs]: 0;
53
}
54
 
55
static int of_call_prom_ret(const char *service, int nargs, int nret,
56
                            unsigned int *rets, ...)
57
{
58
        int i;
59
        struct prom_args {
60
                const char *service;
61
                int nargs;
62
                int nret;
63
                unsigned int args[12];
64
        } args;
65
        va_list list;
66
 
67
        args.service = service;
68
        args.nargs = nargs;
69
        args.nret = nret;
70
 
71
        va_start(list, rets);
72
        for (i = 0; i < nargs; i++)
73
                args.args[i] = va_arg(list, unsigned int);
74
        va_end(list);
75
 
76
        for (i = 0; i < nret; i++)
77
                args.args[nargs+i] = 0;
78
 
79
        if (prom(&args) < 0)
80
                return -1;
81
 
82
        if (rets != (void *) 0)
83
                for (i = 1; i < nret; ++i)
84
                        rets[i-1] = args.args[nargs+i];
85
 
86
        return (nret > 0)? args.args[nargs]: 0;
87
}
88
 
89
/* returns true if s2 is a prefix of s1 */
90
static int string_match(const char *s1, const char *s2)
91
{
92
        for (; *s2; ++s2)
93
                if (*s1++ != *s2)
94
                        return 0;
95
        return 1;
96
}
97
 
98
/*
99
 * Older OF's require that when claiming a specific range of addresses,
100
 * we claim the physical space in the /memory node and the virtual
101
 * space in the chosen mmu node, and then do a map operation to
102
 * map virtual to physical.
103
 */
104
static int need_map = -1;
105
static ihandle chosen_mmu;
106
static phandle memory;
107
 
108
static int check_of_version(void)
109
{
110
        phandle oprom, chosen;
111
        char version[64];
112
 
113
        oprom = of_finddevice("/openprom");
114
        if (oprom == (phandle) -1)
115
                return 0;
116
        if (of_getprop(oprom, "model", version, sizeof(version)) <= 0)
117
                return 0;
118
        version[sizeof(version)-1] = 0;
119
        printf("OF version = '%s'\r\n", version);
120
        if (!string_match(version, "Open Firmware, 1.")
121
            && !string_match(version, "FirmWorks,3."))
122
                return 0;
123
        chosen = of_finddevice("/chosen");
124
        if (chosen == (phandle) -1) {
125
                chosen = of_finddevice("/chosen@0");
126
                if (chosen == (phandle) -1) {
127
                        printf("no chosen\n");
128
                        return 0;
129
                }
130
        }
131
        if (of_getprop(chosen, "mmu", &chosen_mmu, sizeof(chosen_mmu)) <= 0) {
132
                printf("no mmu\n");
133
                return 0;
134
        }
135
        memory = (ihandle) of_call_prom("open", 1, 1, "/memory");
136
        if (memory == (ihandle) -1) {
137
                memory = (ihandle) of_call_prom("open", 1, 1, "/memory@0");
138
                if (memory == (ihandle) -1) {
139
                        printf("no memory node\n");
140
                        return 0;
141
                }
142
        }
143
        printf("old OF detected\r\n");
144
        return 1;
145
}
146
 
147
void *of_claim(unsigned long virt, unsigned long size, unsigned long align)
148
{
149
        int ret;
150
        unsigned int result;
151
 
152
        if (need_map < 0)
153
                need_map = check_of_version();
154
        if (align || !need_map)
155
                return (void *) of_call_prom("claim", 3, 1, virt, size, align);
156
 
157
        ret = of_call_prom_ret("call-method", 5, 2, &result, "claim", memory,
158
                               align, size, virt);
159
        if (ret != 0 || result == -1)
160
                return (void *) -1;
161
        ret = of_call_prom_ret("call-method", 5, 2, &result, "claim", chosen_mmu,
162
                               align, size, virt);
163
        /* 0x12 == coherent + read/write */
164
        ret = of_call_prom("call-method", 6, 1, "map", chosen_mmu,
165
                           0x12, size, virt, virt);
166
        return (void *) virt;
167
}
168
 
169
void *of_vmlinux_alloc(unsigned long size)
170
{
171
        void *p = malloc(size);
172
 
173
        if (!p)
174
                fatal("Can't allocate memory for kernel image!\n\r");
175
 
176
        return p;
177
}
178
 
179
void of_exit(void)
180
{
181
        of_call_prom("exit", 0, 0);
182
}
183
 
184
/*
185
 * OF device tree routines
186
 */
187
void *of_finddevice(const char *name)
188
{
189
        return (phandle) of_call_prom("finddevice", 1, 1, name);
190
}
191
 
192
int of_getprop(const void *phandle, const char *name, void *buf,
193
               const int buflen)
194
{
195
        return of_call_prom("getprop", 4, 1, phandle, name, buf, buflen);
196
}
197
 
198
int of_setprop(const void *phandle, const char *name, const void *buf,
199
               const int buflen)
200
{
201
        return of_call_prom("setprop", 4, 1, phandle, name, buf, buflen);
202
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.