📄 prom.c
字号:
struct pci_intr_map *imp; pci_addrs = (struct pci_reg_property *) get_property(np, "assigned-addresses", &l); if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) { i = 0; adr = (struct address_range *) mem_start; while ((l -= sizeof(struct pci_reg_property)) >= 0) { /* XXX assumes PCI addresses mapped 1-1 to physical */ adr[i].space = pci_addrs[i].addr.a_hi; adr[i].address = pci_addrs[i].addr.a_lo; adr[i].size = pci_addrs[i].size_lo; ++i; } np->addrs = adr; np->n_addrs = i; mem_start += i * sizeof(struct address_range); } if (use_of_interrupt_tree) return mem_start; /* * If the pci host bridge has an interrupt-map property, * look for our node in it. */ if (np->parent != 0 && pci_addrs != 0 && (imp = (struct pci_intr_map *) get_property(np->parent, "interrupt-map", &ml)) != 0 && (ip = (int *) get_property(np, "interrupts", &l)) != 0) { unsigned int devfn = pci_addrs[0].addr.a_hi & 0xff00; unsigned int cell_size; struct device_node* np2; /* This is hackish, but is only used for BootX booting */ cell_size = sizeof(struct pci_intr_map); np2 = np->parent; while(np2) { if (device_is_compatible(np2, "uni-north")) { cell_size += 4; break; } np2 = np2->parent; } np->n_intrs = 0; np->intrs = (struct interrupt_info *) mem_start; for (i = 0; (ml -= cell_size) >= 0; ++i) { if (imp->addr.a_hi == devfn) { np->intrs[np->n_intrs].line = imp->intr; np->intrs[np->n_intrs].sense = 0; /* FIXME */ ++np->n_intrs; } imp = (struct pci_intr_map *)(((unsigned int)imp) + cell_size); } if (np->n_intrs == 0) np->intrs = 0; mem_start += np->n_intrs * sizeof(struct interrupt_info); return mem_start; } ip = (int *) get_property(np, "AAPL,interrupts", &l); if (ip == 0) ip = (int *) get_property(np, "interrupts", &l); if (ip != 0) { np->intrs = (struct interrupt_info *) mem_start; np->n_intrs = l / sizeof(int); mem_start += np->n_intrs * sizeof(struct interrupt_info); for (i = 0; i < np->n_intrs; ++i) { np->intrs[i].line = *ip++; np->intrs[i].sense = 0; } } return mem_start;}__initstatic unsigned longinterpret_dbdma_props(struct device_node *np, unsigned long mem_start, int naddrc, int nsizec){ struct reg_property *rp; struct address_range *adr; unsigned long base_address; int i, l, *ip; struct device_node *db; base_address = 0; for (db = np->parent; db != NULL; db = db->parent) { if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) { base_address = db->addrs[0].address; break; } } rp = (struct reg_property *) get_property(np, "reg", &l); if (rp != 0 && l >= sizeof(struct reg_property)) { i = 0; adr = (struct address_range *) mem_start; while ((l -= sizeof(struct reg_property)) >= 0) { adr[i].space = 0; adr[i].address = rp[i].address + base_address; adr[i].size = rp[i].size; ++i; } np->addrs = adr; np->n_addrs = i; mem_start += i * sizeof(struct address_range); } if (use_of_interrupt_tree) return mem_start; ip = (int *) get_property(np, "AAPL,interrupts", &l); if (ip == 0) ip = (int *) get_property(np, "interrupts", &l); if (ip != 0) { np->intrs = (struct interrupt_info *) mem_start; np->n_intrs = l / sizeof(int); mem_start += np->n_intrs * sizeof(struct interrupt_info); for (i = 0; i < np->n_intrs; ++i) { np->intrs[i].line = *ip++; np->intrs[i].sense = 0; } } return mem_start;}__initstatic unsigned longinterpret_macio_props(struct device_node *np, unsigned long mem_start, int naddrc, int nsizec){ struct reg_property *rp; struct address_range *adr; unsigned long base_address; int i, l, keylargo, *ip; struct device_node *db; base_address = 0; for (db = np->parent; db != NULL; db = db->parent) { if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) { base_address = db->addrs[0].address; keylargo = device_is_compatible(db, "Keylargo"); break; } } rp = (struct reg_property *) get_property(np, "reg", &l); if (rp != 0 && l >= sizeof(struct reg_property)) { i = 0; adr = (struct address_range *) mem_start; while ((l -= sizeof(struct reg_property)) >= 0) { adr[i].space = 0; adr[i].address = rp[i].address + base_address; adr[i].size = rp[i].size; ++i; } np->addrs = adr; np->n_addrs = i; mem_start += i * sizeof(struct address_range); } if (use_of_interrupt_tree) return mem_start; ip = (int *) get_property(np, "interrupts", &l); if (ip == 0) ip = (int *) get_property(np, "AAPL,interrupts", &l); if (ip != 0) { np->intrs = (struct interrupt_info *) mem_start; if (_machine == _MACH_Pmac) { /* for the iMac */ np->n_intrs = l / sizeof(int); /* Hack for BootX on Core99 */ if (keylargo) np->n_intrs = np->n_intrs/2; for (i = 0; i < np->n_intrs; ++i) { np->intrs[i].line = *ip++; if (keylargo) np->intrs[i].sense = *ip++; else np->intrs[i].sense = 0; } } else { /* CHRP machines */ np->n_intrs = l / (2 * sizeof(int)); for (i = 0; i < np->n_intrs; ++i) { np->intrs[i].line = openpic_to_irq(*ip++); np->intrs[i].sense = *ip++; } } mem_start += np->n_intrs * sizeof(struct interrupt_info); } return mem_start;}__initstatic unsigned longinterpret_isa_props(struct device_node *np, unsigned long mem_start, int naddrc, int nsizec){ struct isa_reg_property *rp; struct address_range *adr; int i, l, *ip; rp = (struct isa_reg_property *) get_property(np, "reg", &l); if (rp != 0 && l >= sizeof(struct isa_reg_property)) { i = 0; adr = (struct address_range *) mem_start; while ((l -= sizeof(struct reg_property)) >= 0) { adr[i].space = rp[i].space; adr[i].address = rp[i].address + (adr[i].space? 0: _ISA_MEM_BASE); adr[i].size = rp[i].size; ++i; } np->addrs = adr; np->n_addrs = i; mem_start += i * sizeof(struct address_range); } if (use_of_interrupt_tree) return mem_start; ip = (int *) get_property(np, "interrupts", &l); if (ip != 0) { np->intrs = (struct interrupt_info *) mem_start; np->n_intrs = l / (2 * sizeof(int)); mem_start += np->n_intrs * sizeof(struct interrupt_info); for (i = 0; i < np->n_intrs; ++i) { np->intrs[i].line = *ip++; np->intrs[i].sense = *ip++; } } return mem_start;}__initstatic unsigned longinterpret_root_props(struct device_node *np, unsigned long mem_start, int naddrc, int nsizec){ struct address_range *adr; int i, l, *ip; unsigned int *rp; int rpsize = (naddrc + nsizec) * sizeof(unsigned int); rp = (unsigned int *) get_property(np, "reg", &l); if (rp != 0 && l >= rpsize) { i = 0; adr = (struct address_range *) mem_start; while ((l -= rpsize) >= 0) { adr[i].space = 0; adr[i].address = rp[naddrc - 1]; adr[i].size = rp[naddrc + nsizec - 1]; ++i; rp += naddrc + nsizec; } np->addrs = adr; np->n_addrs = i; mem_start += i * sizeof(struct address_range); } if (use_of_interrupt_tree) return mem_start; ip = (int *) get_property(np, "AAPL,interrupts", &l); if (ip == 0) ip = (int *) get_property(np, "interrupts", &l); if (ip != 0) { np->intrs = (struct interrupt_info *) mem_start; np->n_intrs = l / sizeof(int); mem_start += np->n_intrs * sizeof(struct interrupt_info); for (i = 0; i < np->n_intrs; ++i) { np->intrs[i].line = *ip++; np->intrs[i].sense = 0; } } return mem_start;}/* * Construct and return a list of the device_nodes with a given name. */__openfirmwarestruct device_node *find_devices(const char *name){ struct device_node *head, **prevp, *np; prevp = &head; for (np = allnodes; np != 0; np = np->allnext) { if (np->name != 0 && strcasecmp(np->name, name) == 0) { *prevp = np; prevp = &np->next; } } *prevp = 0; return head;}/* * Construct and return a list of the device_nodes with a given type. */__openfirmwarestruct device_node *find_type_devices(const char *type){ struct device_node *head, **prevp, *np; prevp = &head; for (np = allnodes; np != 0; np = np->allnext) { if (np->type != 0 && strcasecmp(np->type, type) == 0) { *prevp = np; prevp = &np->next; } } *prevp = 0; return head;}/* Finds a device node given its PCI bus number, device number * and function number */__openfirmwarestruct device_node *find_pci_device_OFnode(unsigned char bus, unsigned char dev_fn){ struct device_node* np; unsigned int *reg; int l; for (np = allnodes; np != 0; np = np->allnext) { int in_macio = 0; struct device_node* parent = np->parent; while(parent) { char *pname = (char *)get_property(parent, "name", &l); if (pname && strcmp(pname, "mac-io") == 0) { in_macio = 1; break; } parent = parent->parent; } if (in_macio) continue; reg = (unsigned int *) get_property(np, "reg", &l); if (reg == 0 || l < sizeof(struct reg_property)) continue; if (((reg[0] >> 8) & 0xff) == dev_fn && ((reg[0] >> 16) & 0xff) == bus) break; } return np;}/* * Returns all nodes linked together */__openfirmwarestruct device_node *find_all_nodes(void){ struct device_node *head, **prevp, *np; prevp = &head; for (np = allnodes; np != 0; np = np->allnext) { *prevp = np; prevp = &np->next; } *prevp = 0; return head;}/* Checks if the given "compat" string matches one of the strings in * the device's "compatible" property */__openfirmwareintdevice_is_compatible(struct device_node *device, const char *compat){ const char* cp; int cplen, l; cp = (char *) get_property(device, "compatible", &cplen); if (cp == NULL) return 0; while (cplen > 0) { if (strncasecmp(cp, compat, strlen(compat)) == 0) return 1; l = strlen(cp) + 1; cp += l; cplen -= l; } return 0;}/* * Indicates whether the root node has a given value in its * compatible property. */__openfirmwareintmachine_is_compatible(const char *compat){ struct device_node *root; root = find_path_device("/"); if (root == 0) return 0; return device_is_compatible(root, compat);}/* * Construct and return a list of the device_nodes with a given type * and compatible property. */__openfirmwarestruct device_node *find_compatible_devices(const char *type, const char *compat){ struct device_node *head, **prevp, *np; prevp = &head; for (np = allnodes; np != 0; np = np->allnext) { if (type != NULL && !(np->type != 0 && strcasecmp(np->type, type) == 0)) continue; if (device_is_compatible(np, compat)) { *prevp = np; prevp = &np->next; } } *prevp = 0; return head;}/* * Find the device_node with a given full_name. */__openfirmwarestruct device_node *find_path_device(const char *path){ struct device_node *np; for (np = allnodes; np != 0; np = np->allnext) if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0) return np; return NULL;}/* * Find the device_node with a given phandle. */__openfirmwarestruct device_node *find_phandle(phandle ph){ struct device_node *np; for (np = allnodes; np != 0; np = np->allnext) if (np->node == ph) return np; return NULL;}/* * Find a property with a given name for a given node * and return the value. */__openfirmwareunsigned char *get_property(struct device_node *np, const char *name, int *lenp){ struct property *pp; for (pp = np->properties; pp != 0; pp = pp->next) if (strcmp(pp->name, name) == 0) { if (lenp != 0) *lenp = pp->length; return pp->value; } return 0;}#if 0__openfirmwarevoidprint_properties(struct device_node *np){ struct property *pp; char *cp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -