HACK
[asbestos.git] / stage2 / device.c
blobd35ce87ca8d05976237b9b0cbc00d62705b93158
1 /* device.c - lv1 device functions
3 Copyright (C) 2010-2011 Hector Martin "marcan" <hector@marcansoft.com>
5 This code is licensed to you under the terms of the GNU GPL, version 2;
6 see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
7 */
9 #include "types.h"
10 #include "lv1call.h"
11 #include "device.h"
12 #include "debug.h"
13 #include "repo.h"
15 int map_dma_mem(int bus_id, int dev_id, void *start, size_t len, u64 *r_bus_addr)
17 s64 result;
18 u64 real_addr = (u64)start;
19 u64 real_end = real_addr + len;
20 u64 map_start = real_addr & ~0xfff;
21 u64 map_end = (real_end + 0xfff) & ~0xfff;
22 u64 bus_addr;
24 u64 flags = 0xf800000000000000UL;
26 result = lv1_allocate_device_dma_region(bus_id, dev_id, map_end - map_start, 12, 0, &bus_addr);
27 if (result)
28 return result;
30 result = lv1_map_device_dma_region(bus_id, dev_id, map_start, bus_addr, map_end - map_start, flags);
31 if (result) {
32 lv1_free_device_dma_region(bus_id, dev_id, bus_addr);
33 return result;
36 *r_bus_addr = bus_addr + real_addr - map_start;
37 return 0;
40 int unmap_dma_mem(int bus_id, int dev_id, u64 bus_addr, size_t len)
42 s64 result;
43 u64 real_bus_addr;
45 real_bus_addr = bus_addr & ~0xfff;
46 len += bus_addr - real_bus_addr;
47 len = (len + 0xfff) & ~0xfff;
49 result = lv1_unmap_device_dma_region(bus_id, dev_id, real_bus_addr, len);
50 if (result)
51 return result;
53 return lv1_free_device_dma_region(bus_id, dev_id, real_bus_addr);
56 int find_device_by_type(int bustype, int type, int index, int *pbus_id, int *pdev_id, int *pirq)
58 u64 v2;
59 u64 bus_ndx;
60 s64 result;
62 printf("Locating device with type %d and index %d...\n", type, index);
63 for (bus_ndx=0; bus_ndx<10; bus_ndx++) {
64 u64 bus_id=0, bus_type=0, num_dev=0;
66 result = lv1_read_repository_node(PS3_LPAR_ID_PME, FIELD_FIRST("bus",bus_ndx),
67 FIELD("type",0), 0, 0, &bus_type, &v2);
68 if (result)
69 continue;
70 result = lv1_read_repository_node(PS3_LPAR_ID_PME, FIELD_FIRST("bus",bus_ndx),
71 FIELD("id",0), 0, 0, &bus_id, &v2);
72 if (result)
73 continue;
74 result = lv1_read_repository_node(PS3_LPAR_ID_PME, FIELD_FIRST("bus",bus_ndx),
75 FIELD("num_dev",0), 0, 0, &num_dev, &v2);
76 if (result)
77 continue;
79 if (bus_type != bustype)
80 continue;
82 //printf("Bus #%ld id %ld type %ld num_dev %ld\n", bus_ndx, bus_id, bus_type, num_dev);
83 u64 dev_ndx;
84 for (dev_ndx=0; dev_ndx<num_dev; dev_ndx++) {
85 s64 dev_id=0, dev_type=0, dev_intr=0;
87 result = lv1_read_repository_node(PS3_LPAR_ID_PME, FIELD_FIRST("bus",bus_ndx),
88 FIELD("dev",dev_ndx), FIELD("id",0), 0, (u64*)&dev_id, &v2);
89 if (result)
90 dev_id = -1;
91 result = lv1_read_repository_node(PS3_LPAR_ID_PME, FIELD_FIRST("bus",bus_ndx),
92 FIELD("dev",dev_ndx), FIELD("type",0), 0, (u64*)&dev_type, &v2);
93 if (result)
94 dev_type = -1;
95 result = lv1_read_repository_node(PS3_LPAR_ID_PME, FIELD_FIRST("bus",bus_ndx),
96 FIELD("dev",dev_ndx), FIELD("intr",0), 0, (u64*)&dev_intr, &v2);
97 if (result)
98 dev_intr = -1;
100 //printf("- Dev #%ld id %ld type %ld intr %ld\n", dev_ndx, dev_id, dev_type, dev_intr);
101 if (dev_type == type) {
102 if (index) {
103 index--;
104 continue;
106 printf("Device found: bus #%ld id %ld type %ld, dev #%ld id %ld type %ld intr %ld\n",
107 bus_ndx, bus_id, bus_type, dev_ndx, dev_id, dev_type, dev_intr);
108 if (pbus_id)
109 *pbus_id = bus_id;
110 if (pdev_id)
111 *pdev_id = dev_id;
112 if (pirq)
113 *pirq = dev_intr;
114 return 0;
119 printf("Device not found\n");
120 return -1;
123 int close_all_devs(void)
125 u64 v2;
126 u64 bus_ndx;
127 s64 result;
128 int gelic_bus, gelic_dev;
130 if (find_device_by_type(BUS_TYPE_SB, DEV_TYPE_ETH, 0, &gelic_bus, &gelic_dev, NULL) != 0) {
131 gelic_bus = gelic_dev = -1;
134 int closed = 0;
136 printf("Closing all devices...\n");
137 for (bus_ndx=0; bus_ndx<10; bus_ndx++) {
138 u64 bus_id=0, bus_type=0, num_dev=0;
140 result = lv1_read_repository_node(PS3_LPAR_ID_PME, FIELD_FIRST("bus",bus_ndx),
141 FIELD("type",0), 0, 0, &bus_type, &v2);
142 if (result)
143 continue;
144 result = lv1_read_repository_node(PS3_LPAR_ID_PME, FIELD_FIRST("bus",bus_ndx),
145 FIELD("id",0), 0, 0, &bus_id, &v2);
146 if (result)
147 continue;
148 result = lv1_read_repository_node(PS3_LPAR_ID_PME, FIELD_FIRST("bus",bus_ndx),
149 FIELD("num_dev",0), 0, 0, &num_dev, &v2);
150 if (result)
151 continue;
153 printf("Bus #%ld id %ld type %ld num_dev %ld\n", bus_ndx, bus_id, bus_type, num_dev);
154 u64 dev_ndx;
155 for (dev_ndx=0; dev_ndx<num_dev; dev_ndx++) {
156 s64 dev_id=0, dev_type=0, dev_intr=0;
158 result = lv1_read_repository_node(PS3_LPAR_ID_PME, FIELD_FIRST("bus",bus_ndx),
159 FIELD("dev",dev_ndx), FIELD("id",0), 0, (u64*)&dev_id, &v2);
160 if (result)
161 dev_id = -1;
162 result = lv1_read_repository_node(PS3_LPAR_ID_PME, FIELD_FIRST("bus",bus_ndx),
163 FIELD("dev",dev_ndx), FIELD("type",0), 0, (u64*)&dev_type, &v2);
164 if (result)
165 dev_type = -1;
166 result = lv1_read_repository_node(PS3_LPAR_ID_PME, FIELD_FIRST("bus",bus_ndx),
167 FIELD("dev",dev_ndx), FIELD("intr",0), 0, (u64*)&dev_intr, &v2);
168 if (result)
169 dev_intr = -1;
171 printf("- Dev #%ld id %ld type %ld intr %ld ", dev_ndx, dev_id, dev_type, dev_intr);
172 if (bus_id == gelic_bus && dev_id == gelic_dev)
173 printf("KEPT (gelic)\n");
174 else if (lv1_close_device(bus_id, dev_id) == 0) {
175 printf("CLOSED\n");
176 closed++;
177 } else {
178 printf("\n");
182 return closed;