|
|
1.1 root 1: /*
2: * derived from mol/mol.c,
3: * Copyright (C) 2003, 2004 Samuel Rydh ([email protected])
4: *
5: * This program is free software; you can redistribute it and/or
6: * modify it under the terms of the GNU General Public License
7: * version 2
8: *
9: */
10:
11: #include "config.h"
12: #include "arch/common/nvram.h"
13: #include "packages/nvram.h"
14: #include "libopenbios/bindings.h"
15: #include "libc/byteorder.h"
16: #include "libc/vsprintf.h"
17:
18: #include "drivers/drivers.h"
19: #include "macio.h"
20: #include "cuda.h"
21: #include "escc.h"
22: #include "drivers/pci.h"
23:
24: #define OW_IO_NVRAM_SIZE 0x00020000
25: #define OW_IO_NVRAM_OFFSET 0x00060000
26: #define OW_IO_NVRAM_SHIFT 4
27:
28: #define NW_IO_NVRAM_SIZE 0x00004000
29: #define NW_IO_NVRAM_OFFSET 0xfff04000
30: #define NW_IO_NVRAM_SHIFT 1
31:
32: #define IO_OPENPIC_SIZE 0x00040000
33: #define IO_OPENPIC_OFFSET 0x00040000
34:
35: static char *nvram;
36:
37: int
38: arch_nvram_size( void )
39: {
40: if (is_oldworld())
41: return OW_IO_NVRAM_SIZE >> OW_IO_NVRAM_SHIFT;
42: else
43: return NW_IO_NVRAM_SIZE >> NW_IO_NVRAM_SHIFT;
44: }
45:
46: void macio_nvram_init(const char *path, phys_addr_t addr)
47: {
48: phandle_t chosen, aliases;
49: phandle_t dnode;
50: int props[2];
51: char buf[64];
52: unsigned long nvram_size, nvram_offset;
53:
54: if (is_oldworld()) {
55: nvram_offset = OW_IO_NVRAM_OFFSET;
56: nvram_size = OW_IO_NVRAM_SIZE;
57: } else {
58: nvram_offset = NW_IO_NVRAM_OFFSET;
59: nvram_size = NW_IO_NVRAM_SIZE;
60: push_str("/");
61: fword("find-device");
62: fword("new-device");
63: push_str("nvram");
64: fword("device-name");
65: fword("finish-device");
66: }
67: nvram = (char*)addr + nvram_offset;
68: snprintf(buf, sizeof(buf), "%s/nvram", path);
69: nvram_init(buf);
70: dnode = find_dev(buf);
71: set_int_property(dnode, "#bytes", arch_nvram_size() );
72: props[0] = __cpu_to_be32(nvram_offset);
73: props[1] = __cpu_to_be32(nvram_size);
74: set_property(dnode, "reg", (char *)&props, sizeof(props));
75: set_property(dnode, "device_type", "nvram", 6);
76: NEWWORLD(set_property(dnode, "compatible", "nvram,flash", 12));
77:
78: chosen = find_dev("/chosen");
79: push_str(buf);
80: fword("open-dev");
81: set_int_property(chosen, "nvram", POP());
82:
83: aliases = find_dev("/aliases");
84: set_property(aliases, "nvram", buf, strlen(buf) + 1);
85: }
86:
87: #ifdef DUMP_NVRAM
88: static void
89: dump_nvram(void)
90: {
91: int i, j;
92: for (i = 0; i < 10; i++)
93: {
94: for (j = 0; j < 16; j++)
95: printk ("%02x ", nvram[(i*16+j)<<4]);
96: printk (" ");
97: for (j = 0; j < 16; j++)
98: if (isprint(nvram[(i*16+j)<<4]))
99: printk("%c", nvram[(i*16+j)<<4]);
100: else
101: printk(".");
102: printk ("\n");
103: }
104: }
105: #endif
106:
107:
108: void
109: arch_nvram_put( char *buf )
110: {
111: int i;
112: unsigned int it_shift;
113:
114: if (is_oldworld())
115: it_shift = OW_IO_NVRAM_SHIFT;
116: else
117: it_shift = NW_IO_NVRAM_SHIFT;
118:
119: for (i=0; i< arch_nvram_size() ; i++)
120: nvram[i << it_shift] = buf[i];
121: #ifdef DUMP_NVRAM
122: printk("new nvram:\n");
123: dump_nvram();
124: #endif
125: }
126:
127: void
128: arch_nvram_get( char *buf )
129: {
130: int i;
131: unsigned int it_shift;
132:
133: if (is_oldworld())
134: it_shift = OW_IO_NVRAM_SHIFT;
135: else
136: it_shift = NW_IO_NVRAM_SHIFT;
137:
138: for (i=0; i< arch_nvram_size(); i++)
139: buf[i] = nvram[i << it_shift];
140:
141: #ifdef DUMP_NVRAM
142: printk("current nvram:\n");
143: dump_nvram();
144: #endif
145: }
146:
147: static void
148: openpic_init(const char *path, phys_addr_t addr)
149: {
150: phandle_t target_node;
151: phandle_t dnode;
152: int props[2];
153: char buf[128];
154:
155: push_str(path);
156: fword("find-device");
157: fword("new-device");
158: push_str("interrupt-controller");
159: fword("device-name");
160:
161: snprintf(buf, sizeof(buf), "%s/interrupt-controller", path);
162: dnode = find_dev(buf);
163: set_property(dnode, "device_type", "open-pic", 9);
164: set_property(dnode, "compatible", "chrp,open-pic", 14);
165: set_property(dnode, "built-in", "", 0);
166: props[0] = __cpu_to_be32(IO_OPENPIC_OFFSET);
167: props[1] = __cpu_to_be32(IO_OPENPIC_SIZE);
168: set_property(dnode, "reg", (char *)&props, sizeof(props));
169: set_int_property(dnode, "#interrupt-cells", 2);
170: set_int_property(dnode, "#address-cells", 0);
171: set_property(dnode, "interrupt-controller", "", 0);
172: set_int_property(dnode, "clock-frequency", 4166666);
173:
174: fword("finish-device");
175:
176: if (is_newworld()) {
177: u32 *interrupt_map;
178: int len, i;
179:
180: /* patch in interrupt parent */
181: dnode = find_dev(buf);
182:
183: target_node = find_dev("/pci/mac-io");
184: set_int_property(target_node, "interrupt-parent", dnode);
185:
186: target_node = find_dev("/pci/mac-io/escc/ch-a");
187: set_int_property(target_node, "interrupt-parent", dnode);
188:
189: target_node = find_dev("/pci/mac-io/escc/ch-b");
190: set_int_property(target_node, "interrupt-parent", dnode);
191:
192: target_node = find_dev("/pci");
193: set_int_property(target_node, "interrupt-parent", dnode);
194:
195: interrupt_map = (u32 *)get_property(target_node, "interrupt-map", &len);
196: for (i = 0; i < 4; i++) {
197: interrupt_map[(i * 7) + PCI_INT_MAP_PIC_HANDLE] = (u32)dnode;
198: }
199: set_property(target_node, "interrupt-map", (char *)interrupt_map, len);
200: }
201: }
202:
203: DECLARE_NODE(ob_macio, INSTALL_OPEN, sizeof(int), "Tmac-io");
204:
205: /* ( str len -- addr ) */
206:
207: static void
208: ob_macio_decode_unit(void *private)
209: {
210: ucell addr;
211:
212: const char *arg = pop_fstr_copy();
213:
214: addr = strtol(arg, NULL, 16);
215:
216: free((char*)arg);
217:
218: PUSH(addr);
219: }
220:
221: /* ( addr -- str len ) */
222:
223: static void
224: ob_macio_encode_unit(void *private)
225: {
226: char buf[8];
227:
228: ucell addr = POP();
229:
230: snprintf(buf, sizeof(buf), "%x", addr);
231:
232: push_str(buf);
233: }
234:
235: NODE_METHODS(ob_macio) = {
236: { "decode-unit", ob_macio_decode_unit },
237: { "encode-unit", ob_macio_encode_unit },
238: };
239:
240: void
241: ob_macio_heathrow_init(const char *path, phys_addr_t addr)
242: {
243: phandle_t aliases;
244:
245: REGISTER_NODE(ob_macio);
246: aliases = find_dev("/aliases");
247: set_property(aliases, "mac-io", path, strlen(path) + 1);
248:
249: cuda_init(path, addr);
250: macio_nvram_init(path, addr);
251: escc_init(path, addr);
252: macio_ide_init(path, addr, 1);
253: }
254:
255: void
256: ob_macio_keylargo_init(const char *path, phys_addr_t addr)
257: {
258: phandle_t aliases;
259:
260: aliases = find_dev("/aliases");
261: set_property(aliases, "mac-io", path, strlen(path) + 1);
262:
263: cuda_init(path, addr);
264: /* The NewWorld NVRAM is not located in the MacIO device */
265: macio_nvram_init("", 0);
266: escc_init(path, addr);
267: macio_ide_init(path, addr, 3);
268: openpic_init(path, addr);
269: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.