Changeset e731b0d in mainline for boot/genarch
- Timestamp:
- 2009-08-20T16:58:55Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b9c7425
- Parents:
- a11099f
- Location:
- boot/genarch
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
boot/genarch/balloc.c
ra11099f re731b0d 28 28 29 29 #include <balloc.h> 30 #include <asm.h> 30 31 #include <types.h> 31 32 #include <align.h> 32 33 33 34 static ballocs_t *ballocs; 35 static uintptr_t phys_base; 34 36 35 void balloc_init(ballocs_t *b , uintptr_tbase)37 void balloc_init(ballocs_t *ball, uintptr_t base, uintptr_t kernel_base) 36 38 { 37 ballocs = b; 38 ballocs->base = base; 39 ballocs = ball; 40 phys_base = base; 41 ballocs->base = kernel_base; 39 42 ballocs->size = 0; 40 43 } … … 42 45 void *balloc(size_t size, size_t alignment) 43 46 { 44 uintptr_t addr;45 46 47 /* Enforce minimal alignment. */ 47 48 alignment = ALIGN_UP(alignment, 4); 48 49 49 addr = ballocs->base + ALIGN_UP(ballocs->size, alignment);50 50 uintptr_t addr = phys_base + ALIGN_UP(ballocs->size, alignment); 51 51 52 if (ALIGN_UP(ballocs->size, alignment) + size > BALLOC_MAX_SIZE) 52 53 return NULL; 53 54 54 55 ballocs->size = ALIGN_UP(ballocs->size, alignment) + size; 55 56 56 57 return (void *) addr; 57 58 } 59 60 void *balloc_rebase(void *ptr) 61 { 62 return (void *) ((uintptr_t) ptr - phys_base + ballocs->base); 63 } -
boot/genarch/balloc.h
ra11099f re731b0d 32 32 #include <types.h> 33 33 34 #define BALLOC_MAX_SIZE (128 * 1024)35 36 34 typedef struct { 37 35 uintptr_t base; … … 39 37 } ballocs_t; 40 38 41 extern void balloc_init(ballocs_t *b , uintptr_tbase);39 extern void balloc_init(ballocs_t *ball, uintptr_t base, uintptr_t kernel_base); 42 40 extern void *balloc(size_t size, size_t alignment); 41 extern void *balloc_rebase(void *ptr); 43 42 44 43 #endif -
boot/genarch/ofw.c
ra11099f re731b0d 33 33 #include <types.h> 34 34 35 #define RED(i) (((i) >> 5) & ((1 << 3) - 1)) 36 #define GREEN(i) (((i) >> 3) & ((1 << 2) - 1)) 37 #define BLUE(i) ((i) & ((1 << 3) - 1)) 38 #define CLIP(i) ((i) <= 255 ? (i) : 255) 39 35 40 uintptr_t ofw_cif; 36 41 … … 85 90 /** Perform a call to OpenFirmware client interface. 86 91 * 87 * @param service String identifying the service requested. 88 * @param nargs Number of input arguments. 89 * @param nret Number of output arguments. This includes the return 90 * value. 91 * @param rets Buffer for output arguments or NULL. The buffer must 92 * accommodate nret - 1 items. 93 * 94 * @return Return value returned by the client interface. 92 * @param service String identifying the service requested. 93 * @param nargs Number of input arguments. 94 * @param nret Number of output arguments. This includes the return 95 * value. 96 * @param rets Buffer for output arguments or NULL. The buffer must 97 * accommodate nret - 1 items. 98 * 99 * @return Return value returned by the client interface. 100 * 95 101 */ 96 102 unsigned long … … 221 227 } 222 228 223 void *ofw_claim_virt(const void *virt, const int len)229 void *ofw_claim_virt(const void *virt, const unsigned int len) 224 230 { 225 231 ofw_arg_t retaddr; … … 234 240 } 235 241 236 void *ofw_claim_phys(const void *phys, const int len) 237 { 238 ofw_arg_t retaddr[2]; 239 int shift; 240 242 static void *ofw_claim_phys_internal(const void *phys, const unsigned int len, const unsigned int alignment) 243 { 244 /* 245 * Note that the return value check will help 246 * us to discover conflicts between OpenFirmware 247 * allocations and our use of physical memory. 248 * It is better to detect collisions here 249 * than to cope with weird errors later. 250 * 251 * So this is really not to make the loader 252 * more generic; it is here for debugging 253 * purposes. 254 */ 255 241 256 if (sizeof(unative_t) == 8) { 242 shift = 32; 257 ofw_arg_t retaddr[2]; 258 int shift = 32; 259 243 260 if (ofw_call("call-method", 6, 3, retaddr, "claim", 244 ofw_memory_prop, 0, len, ((uintptr_t) phys) >> shift,261 ofw_memory_prop, alignment, len, ((uintptr_t) phys) >> shift, 245 262 ((uintptr_t) phys) & ((uint32_t) -1)) != 0) { 246 /*247 * Note that this will help us to discover248 * conflicts between OpenFirmware allocations249 * and our use of physical memory.250 * It is better to detect collisions here251 * than to cope with weird errors later.252 *253 * So this is really not to make the loader254 * more generic; it is here for debugging255 * purposes.256 */257 263 puts("Error: memory method claim() failed, halting.\n"); 258 264 halt(); 259 265 } 266 267 return (void *) ((retaddr[0] << shift) | retaddr[1]); 260 268 } else { 261 shift = 0; 262 /* 263 * FIXME: the number of arguments is probably different... 264 */ 265 puts("Error: 32-bit ofw_claim_phys not implemented.\n"); 266 halt(); 267 } 268 269 return (void *) ((retaddr[0] << shift) | retaddr[1]); 270 } 271 272 int ofw_map(const void *phys, const void *virt, const int size, const int mode) 269 ofw_arg_t retaddr[1]; 270 271 if (ofw_call("call-method", 5, 2, retaddr, "claim", 272 ofw_memory_prop, alignment, len, (uintptr_t) phys) != 0) { 273 puts("Error: memory method claim() failed, halting.\n"); 274 halt(); 275 } 276 277 return (void *) retaddr[0]; 278 } 279 } 280 281 void *ofw_claim_phys(const void *phys, const unsigned int len) 282 { 283 return ofw_claim_phys_internal(phys, len, 0); 284 } 285 286 void *ofw_claim_phys_any(const unsigned int len, const unsigned int alignment) 287 { 288 return ofw_claim_phys_internal(NULL, len, alignment); 289 } 290 291 int ofw_map(const void *phys, const void *virt, const unsigned int size, const int mode) 273 292 { 274 293 uintptr_t phys_hi, phys_lo; … … 314 333 315 334 /* 316 * This is a hot fix of the issue which occurs on machines317 * where there are holes in the physical memory (such as318 * SunBlade 1500). Should we detect a hole in the physical319 * memory, we will ignore any memory detected behind320 * the hole and pretend the hole does not exist.335 * This is a hot fix of the issue which occurs on machines 336 * where there are holes in the physical memory (such as 337 * SunBlade 1500). Should we detect a hole in the physical 338 * memory, we will ignore any memory detected behind 339 * the hole and pretend the hole does not exist. 321 340 */ 322 341 if ((map->count > 0) && (map->zones[map->count - 1].start + … … 335 354 } 336 355 337 int ofw_screen(screen_t *screen)338 {339 char device_name[BUF_SIZE];340 uint32_t virtaddr;341 342 if (ofw_get_property(ofw_aliases, "screen", device_name,343 sizeof(device_name)) <= 0)344 return false;345 346 phandle device = ofw_find_device(device_name);347 if (device == -1)348 return false;349 350 if (ofw_get_property(device, "address", &virtaddr,351 sizeof(virtaddr)) <= 0)352 return false;353 354 screen->addr = (void *) ((uintptr_t) virtaddr);355 356 if (ofw_get_property(device, "width", &screen->width,357 sizeof(screen->width)) <= 0)358 return false;359 360 if (ofw_get_property(device, "height", &screen->height,361 sizeof(screen->height)) <= 0)362 return false;363 364 if (ofw_get_property(device, "depth", &screen->bpp,365 sizeof(screen->bpp)) <= 0)366 return false;367 368 if (ofw_get_property(device, "linebytes", &screen->scanline,369 sizeof(screen->scanline)) <= 0)370 return false;371 372 return true;373 }374 375 #define RED(i) (((i) >> 5) & ((1 << 3) - 1))376 #define GREEN(i) (((i) >> 3) & ((1 << 2) - 1))377 #define BLUE(i) ((i) & ((1 << 3) - 1))378 #define CLIP(i) ((i) <= 255 ? (i) : 255)379 380 381 356 /** 382 357 * Sets up the palette for the 8-bit color depth configuration so that the … … 392 367 char device_name[BUF_SIZE]; 393 368 394 /* resolve alias */369 /* Resolve alias */ 395 370 if (ofw_get_property(ofw_aliases, "screen", device_name, 396 371 sizeof(device_name)) <= 0) 397 372 return false; 398 373 399 /* for depth greater than 8 it makes no sense to set up the palette */374 /* For depth greater than 8 it makes no sense to set up the palette */ 400 375 uint32_t depth; 401 376 phandle device = ofw_find_device(device_name); … … 407 382 return false; 408 383 409 /* required in order to be able to make a method call */384 /* Required in order to be able to make a method call */ 410 385 ihandle screen = ofw_open(device_name); 411 386 if (screen == -1) 412 387 return false; 413 388 414 /* setup the palette so that the (inverted) 3:2:3 scheme is usable */389 /* Setup the palette so that the (inverted) 3:2:3 scheme is usable */ 415 390 unsigned int i; 416 391 for (i = 0; i < 256; i++) -
boot/genarch/ofw.h
ra11099f re731b0d 33 33 #include <stdarg.h> 34 34 35 #define BUF_SIZE 102435 #define BUF_SIZE 1024 36 36 37 #define MEMMAP_MAX_RECORDS 3237 #define MEMMAP_MAX_RECORDS 32 38 38 39 #define MAX_OFW_ARGS 1239 #define MAX_OFW_ARGS 12 40 40 41 41 typedef unative_t ofw_arg_t; … … 47 47 */ 48 48 typedef struct { 49 ofw_arg_t service; /**< Command name. */50 ofw_arg_t nargs; /**< Number of in arguments. */51 ofw_arg_t nret; /**< Number of out arguments. */52 ofw_arg_t args[MAX_OFW_ARGS]; /**< List of arguments. */49 ofw_arg_t service; /**< Command name. */ 50 ofw_arg_t nargs; /**< Number of in arguments. */ 51 ofw_arg_t nret; /**< Number of out arguments. */ 52 ofw_arg_t args[MAX_OFW_ARGS]; /**< List of arguments. */ 53 53 } ofw_args_t; 54 54 … … 63 63 memzone_t zones[MEMMAP_MAX_RECORDS]; 64 64 } memmap_t; 65 66 typedef struct {67 void *addr;68 uint32_t width;69 uint32_t height;70 uint32_t bpp;71 uint32_t scanline;72 } screen_t;73 74 typedef struct {75 void *addr;76 uint32_t size;77 } macio_t;78 65 79 66 typedef struct { … … 118 105 extern void *ofw_translate(const void *virt); 119 106 extern int ofw_translate_failed(ofw_arg_t flag); 120 extern void *ofw_claim_virt(const void *virt, const int len); 121 extern void *ofw_claim_phys(const void *virt, const int len); 122 extern int ofw_map(const void *phys, const void *virt, const int size, const int mode); 107 extern void *ofw_claim_virt(const void *virt, const unsigned int len); 108 extern void *ofw_claim_phys(const void *virt, const unsigned int len); 109 extern void *ofw_claim_phys_any(const unsigned int len, const unsigned int alignment); 110 extern int ofw_map(const void *phys, const void *virt, const unsigned int size, const int mode); 123 111 extern int ofw_memmap(memmap_t *map); 124 extern int ofw_screen(screen_t *screen);125 extern int ofw_macio(macio_t *macio);126 112 extern int ofw_setup_palette(void); 127 113 extern void ofw_quiesce(void); -
boot/genarch/ofw_tree.c
ra11099f re731b0d 29 29 #include <ofw_tree.h> 30 30 #include <ofw.h> 31 #include <ofwarch.h> 31 32 #include <types.h> 32 33 #include <string.h> 33 34 #include <balloc.h> 34 35 #include <asm.h> 35 36 #define MAX_PATH_LEN 256 36 #include <memstr.h> 37 38 #define MAX_PATH_LEN 256 37 39 38 40 static ofw_tree_node_t *ofw_tree_node_alloc(void) … … 49 51 static void *ofw_tree_space_alloc(size_t size) 50 52 { 51 char *addr;52 53 53 /* 54 54 * What we do here is a nasty hack :-) … … 61 61 * behind the requested memory. 62 62 */ 63 addr = balloc(size + 1, size);63 char *addr = balloc(size + 1, size); 64 64 if (addr) 65 65 addr[size] = '\0'; 66 66 67 return addr; 67 68 } … … 75 76 * order to prevent stack from overflowing. 76 77 * 77 * @param current_node Pointer to uninitialized ofw_tree_node structure that 78 * will become the memory represenation of 'current'. 79 * @param parent_node Parent ofw_tree_node structure or NULL in case of root 80 * node. 81 * @param current OpenFirmware phandle to the current device tree node. 78 * @param current_node Pointer to uninitialized ofw_tree_node structure that 79 * will become the memory represenation of 'current'. 80 * @param parent_node Parent ofw_tree_node structure or NULL in case of root 81 * node. 82 * @param current OpenFirmware phandle to the current device tree node. 83 * 82 84 */ 83 85 static void ofw_tree_node_process(ofw_tree_node_t *current_node, 84 86 ofw_tree_node_t *parent_node, phandle current) 85 87 { 86 static char path[MAX_PATH_LEN + 1];87 static char name[OFW_TREE_PROPERTY_MAX_NAMELEN];88 static char name2[OFW_TREE_PROPERTY_MAX_NAMELEN];89 phandle peer;90 phandle child;91 size_t len;92 int i;93 94 88 while (current_node) { 95 89 /* 96 90 * Initialize node. 97 91 */ 98 current_node->parent = parent_node;92 current_node->parent = (ofw_tree_node_t *) balloc_rebase(parent_node); 99 93 current_node->peer = NULL; 100 94 current_node->child = NULL; … … 103 97 current_node->property = NULL; 104 98 current_node->device = NULL; 105 99 106 100 /* 107 101 * Get the disambigued name. 108 102 */ 109 len = ofw_package_to_path(current, path, MAX_PATH_LEN); 103 static char path[MAX_PATH_LEN + 1]; 104 size_t len = ofw_package_to_path(current, path, MAX_PATH_LEN); 110 105 if (len == -1) 111 106 return; 112 107 113 108 path[len] = '\0'; 114 for (i = len - 1; i >= 0 && path[i] != '/'; i--) 115 ; 116 i++; /* do not include '/' */ 117 109 110 /* Find last slash */ 111 int i; 112 for (i = len - 1; (i >= 0) && (path[i] != '/'); i--); 113 114 /* Do not include the slash */ 115 i++; 118 116 len -= i; 119 120 /* add space for trailing '\0' */ 121 current_node->da_name = ofw_tree_space_alloc(len + 1); 122 if (!current_node->da_name) 123 return; 124 125 memcpy(current_node->da_name, &path[i], len); 126 current_node->da_name[len] = '\0'; 127 117 118 /* Add space for trailing '\0' */ 119 char *da_name = ofw_tree_space_alloc(len + 1); 120 if (!da_name) 121 return; 122 123 memcpy(da_name, &path[i], len); 124 da_name[len] = '\0'; 125 current_node->da_name = (char *) balloc_rebase(da_name); 126 128 127 /* 129 128 * Recursively process the potential child node. 130 129 */ 131 child = ofw_get_child_node(current); 132 if (child != 0 && child != -1) { 133 ofw_tree_node_t *child_node; 134 135 child_node = ofw_tree_node_alloc(); 130 phandle child = ofw_get_child_node(current); 131 if ((child != 0) && (child != -1)) { 132 ofw_tree_node_t *child_node = ofw_tree_node_alloc(); 136 133 if (child_node) { 137 134 ofw_tree_node_process(child_node, current_node, 138 135 child); 139 current_node->child = child_node; 136 current_node->child = 137 (ofw_tree_node_t *) balloc_rebase(child_node); 140 138 } 141 139 } 142 140 143 141 /* 144 142 * Count properties. 145 143 */ 144 static char name[OFW_TREE_PROPERTY_MAX_NAMELEN]; 145 static char name2[OFW_TREE_PROPERTY_MAX_NAMELEN]; 146 146 name[0] = '\0'; 147 147 while (ofw_next_property(current, name, name2) == 1) { … … 149 149 memcpy(name, name2, OFW_TREE_PROPERTY_MAX_NAMELEN); 150 150 } 151 151 152 152 if (!current_node->properties) 153 153 return; 154 154 155 155 /* 156 156 * Copy properties. 157 157 */ 158 current_node->property =158 ofw_tree_property_t *property = 159 159 ofw_tree_properties_alloc(current_node->properties); 160 if (! current_node->property)160 if (!property) 161 161 return; 162 162 163 163 name[0] = '\0'; 164 164 for (i = 0; ofw_next_property(current, name, name2) == 1; i++) { 165 size_t size;166 167 165 if (i == current_node->properties) 168 166 break; 169 167 170 168 memcpy(name, name2, OFW_TREE_PROPERTY_MAX_NAMELEN); 171 memcpy(current_node->property[i].name, name, 172 OFW_TREE_PROPERTY_MAX_NAMELEN); 173 current_node->property[i].name[ 174 OFW_TREE_PROPERTY_MAX_NAMELEN] = '\0'; 175 176 size = ofw_get_proplen(current, name); 177 current_node->property[i].size = size; 169 memcpy(property[i].name, name, OFW_TREE_PROPERTY_MAX_NAMELEN); 170 property[i].name[OFW_TREE_PROPERTY_MAX_NAMELEN] = '\0'; 171 172 size_t size = ofw_get_proplen(current, name); 173 property[i].size = size; 174 178 175 if (size) { 179 void *buf; 180 181 buf = ofw_tree_space_alloc(size); 182 if (current_node->property[i].value = buf) { 176 void *buf = ofw_tree_space_alloc(size); 177 if (buf) { 183 178 /* 184 179 * Copy property value to memory node. 185 180 */ 186 (void) ofw_get_property(current, name, 187 buf, size);181 (void) ofw_get_property(current, name, buf, size); 182 property[i].value = balloc_rebase(buf); 188 183 } 189 } else { 190 current_node->property[i].value = NULL; 191 } 192 } 193 184 } else 185 property[i].value = NULL; 186 } 187 194 188 /* Just in case we ran out of memory. */ 195 189 current_node->properties = i; 196 190 current_node->property = (ofw_tree_property_t *) balloc_rebase(property); 191 192 197 193 /* 198 194 * Iteratively process the next peer node. … … 202 198 * risk of overflowing the stack is too real. 203 199 */ 204 peer = ofw_get_peer_node(current); 205 if (peer != 0 && peer != -1) { 206 ofw_tree_node_t *peer_node; 207 208 peer_node = ofw_tree_node_alloc(); 209 if (peer_node) { 210 current_node->peer = peer_node; 200 phandle peer = ofw_get_peer_node(current); 201 if ((peer != 0) && (peer != -1)) { 202 ofw_tree_node_t *peer_node = ofw_tree_node_alloc(); 203 if (peer_node) { 204 current_node->peer = (ofw_tree_node_t *) balloc_rebase(peer_node); 211 205 current_node = peer_node; 212 206 current = peer; … … 217 211 } 218 212 } 213 219 214 /* 220 215 * No more peers on this level. … … 226 221 /** Construct memory representation of OpenFirmware device tree. 227 222 * 228 * @return NULL on failure or pointer to the root node. 223 * @return NULL on failure or kernel pointer to the root node. 224 * 229 225 */ 230 226 ofw_tree_node_t *ofw_tree_build(void) 231 227 { 232 ofw_tree_node_t *root; 233 phandle ssm_node; 234 ofw_tree_node_t *ssm; 235 236 root = ofw_tree_node_alloc(); 228 ofw_tree_node_t *root = ofw_tree_node_alloc(); 237 229 if (root) 238 230 ofw_tree_node_process(root, NULL, ofw_root); 239 231 240 232 /* 241 233 * The firmware client interface does not automatically include the … … 243 235 * solution is to explicitly stick "ssm" to the OFW tree. 244 236 */ 245 ssm_node = ofw_find_device("/ssm@0,0");237 phandle ssm_node = ofw_find_device("/ssm@0,0"); 246 238 if (ssm_node != -1) { 247 ssm = ofw_tree_node_alloc();239 ofw_tree_node_t *ssm = ofw_tree_node_alloc(); 248 240 if (ssm) { 249 241 ofw_tree_node_process(ssm, root, 250 242 ofw_find_device("/ssm@0,0")); 251 243 ssm->peer = root->child; 252 root->child = ssm;244 root->child = (ofw_tree_node_t *) balloc_rebase(ssm); 253 245 } 254 246 } 255 247 256 return root;257 } 248 return (ofw_tree_node_t *) balloc_rebase(root); 249 } -
boot/genarch/ofw_tree.h
ra11099f re731b0d 33 33 #include <ofw.h> 34 34 35 #define OFW_TREE_PROPERTY_MAX_NAMELEN 32 36 37 typedef struct ofw_tree_node ofw_tree_node_t; 38 typedef struct ofw_tree_property ofw_tree_property_t; 39 40 /** Memory representation of OpenFirmware device tree node. */ 41 struct ofw_tree_node { 42 ofw_tree_node_t *parent; 43 ofw_tree_node_t *peer; 44 ofw_tree_node_t *child; 45 46 uint32_t node_handle; /**< Old OpenFirmware node handle. */ 47 48 char *da_name; /**< Disambigued name. */ 49 50 unsigned properties; /**< Number of properties. */ 51 ofw_tree_property_t *property; 52 53 void *device; /**< Member used solely by the kernel. */ 54 }; 35 #define OFW_TREE_PROPERTY_MAX_NAMELEN 32 55 36 56 37 /** Memory representation of OpenFirmware device tree node property. */ 57 struct ofw_tree_property{38 typedef struct { 58 39 char name[OFW_TREE_PROPERTY_MAX_NAMELEN]; 59 40 size_t size; 60 41 void *value; 61 }; 42 } ofw_tree_property_t; 43 44 /** Memory representation of OpenFirmware device tree node. */ 45 typedef struct ofw_tree_node { 46 struct ofw_tree_node *parent; 47 struct ofw_tree_node *peer; 48 struct ofw_tree_node *child; 49 50 uint32_t node_handle; /**< Old OpenFirmware node handle. */ 51 52 char *da_name; /**< Disambigued name. */ 53 54 unsigned int properties; /**< Number of properties. */ 55 ofw_tree_property_t *property; 56 57 void *device; /**< Member used solely by the kernel. */ 58 } ofw_tree_node_t; 62 59 63 60 extern ofw_tree_node_t *ofw_tree_build(void);
Note:
See TracChangeset
for help on using the changeset viewer.
