Пример #1
0
/*
 * The first psycho must always programmed up for the system clock and error
 * handling purposes.
 */
static void
have_pci(pnode_t node)
{
    int size;
    uint_t portid;
    char compatible[OBP_MAXDRVNAME];

    size = GETPROPLEN(node, "portid");
    if (size == -1) size = GETPROPLEN(node, "upa-portid");
    if (size == -1)
        return;
    if (size > sizeof (portid))
        cmn_err(CE_PANIC, "portid size wrong");

    if (GETPROP(node, "portid", (caddr_t)&portid) == -1)
        if (GETPROP(node, "upa-portid", (caddr_t)&portid) == -1)
            cmn_err(CE_PANIC, "portid not found");

    niobus++;


    /*
     * Need two physical TSBs for Schizo compatible nodes,
     * one otherwise.
     */
    compatible[0] = '\0';
    (void) prom_getprop(node, OBP_COMPATIBLE, compatible);
    if (strcmp(compatible, "pci108e,8001") == 0)
        niommu_tsbs += IOMMU_PER_SCHIZO;
    else
        niommu_tsbs++;
}
Пример #2
0
void get_drone_ip(void)
{
    int ret;
    char prop_value[PROP_VALUE_MAX];
    char prop_name[PROP_NAME_MAX];
    int inet_part[4];

    // quick and dirty way to guess Drone IP address
    ret = GETPROP("wifi.interface", prop_value);
    if (ret > 0) {
        INFO("wifi interface = %s\n", prop_value);
        snprintf(prop_name, PROP_NAME_MAX, "dhcp.%s.ipaddress", prop_value);
        ret = GETPROP(prop_name, prop_value);
    }
    if (ret > 0) {
        INFO("IP address = %s\n", prop_value);
        ret = 0;
        if (sscanf(prop_value, "%d.%d.%d.%d",
                   &inet_part[0],
                   &inet_part[1],
                   &inet_part[2],
                   &inet_part[3]) == 4) {
            ret = 1;
            sprintf(drone_ip, "%u.%u.%u.%u",
                    inet_part[0]& 0xff, inet_part[1]& 0xff, inet_part[2]&0xff,
                    WIFI_ARDRONE_ADDR_LAST_BYTE);
        }
    }
    if (ret == 0) {
        // fallback to default address
        sprintf(drone_ip, WIFI_ARDRONE_IP);
    }

    INFO("assuming drone IP address is %s\n", drone_ip);
}
Пример #3
0
/*
 * The first eeprom is used as the TOD clock, referenced
 * by v_eeprom_addr in locore.s.
 */
static void
have_eeprom(pnode_t node)
{
    int size;
    uint32_t eaddr;

    /*
     * "todmostek" module will be selected based on finding a "model"
     * property value of "mk48t59" in the "eeprom" node.
     */
    if (tod_module_name == NULL) {
        char buf[MAXSYSNAME];

        if ((GETPROP(node, "model", buf) != -1) &&
                (strcmp(buf, "mk48t59") == 0))
            tod_module_name = "todmostek";
    }

    /*
     * If we have found two distinct eeprom's, then we're done.
     */
    if (v_eeprom_addr && v_timecheck_addr != v_eeprom_addr)
        return;

    /*
     * multiple eeproms may exist but at least
     * one must have an "address" property
     */
    if ((size = GETPROPLEN(node, OBP_ADDRESS)) == -1)
        return;
    if (size != sizeof (eaddr))
        cmn_err(CE_PANIC, "eeprom addr size");
    if (GETPROP(node, OBP_ADDRESS, (caddr_t)&eaddr) == -1)
        cmn_err(CE_PANIC, "eeprom addr");

    /*
     * If we have a chosen eeprom and it is not this node, keep looking.
     */
    if (chosen_eeprom != NULL && chosen_eeprom != node) {
        v_timecheck_addr = (caddr_t)(uintptr_t)eaddr;
        return;
    }

    v_eeprom_addr = (caddr_t)(uintptr_t)eaddr;

    /*
     * If we don't find an I/O board to use to check the clock,
     * we'll fall back on whichever TOD is available.
     */
    if (v_timecheck_addr == NULL)
        v_timecheck_addr = v_eeprom_addr;

    /*
     * Does this eeprom have watchdog support?
     */
    if (GETPROPLEN(node, WATCHDOG_ENABLE) != -1)
        watchdog_available = 1;
}
Пример #4
0
static void
have_auxio(pnode_t node)
{
    size_t size, n;
    uint32_t addr[5];

    /*
     * Get the size of the auzio's address property.
     * On some platforms, the address property contains one
     * entry and on others it contains five entries.
     * In all cases, the first entries are compatible.
     *
     * This routine gets the address property for the auxio
     * node and stores the first entry in v_auxio_addr which
     * is used by the routine set_auxioreg in sun4u/ml/locore.s.
     */
    if ((size = GETPROPLEN(node, OBP_ADDRESS)) == -1)
        cmn_err(CE_PANIC, "no auxio address property");

    switch (n = (size / sizeof (addr[0]))) {
    case 1:
        break;
    case 5:
        break;
    default:
        cmn_err(CE_PANIC, "auxio addr has %lu entries?", n);
    }

    if (GETPROP(node, OBP_ADDRESS, (caddr_t)addr) == -1)
        cmn_err(CE_PANIC, "auxio addr");

    v_auxio_addr = (caddr_t)(uintptr_t)(addr[0]); /* make into pointer */
}
Пример #5
0
static void
have_pmc(pnode_t node)
{
    uint32_t vaddr;
    pnode_t root;

    /*
     * Watchdog property is in the root node.
     */
    root = prom_nextnode((pnode_t)0);
    if (GETPROPLEN(root, WATCHDOG_ENABLE) != -1) {
        /*
         * The hardware watchdog timer resides within logical
         * unit 8 of SuperI/O. The address property of the node
         * contains the virtual address that we use to program
         * the timer.
         */
        if (GETPROP(node, OBP_ADDRESS, (caddr_t)&vaddr) == -1) {
            watchdog_available = 0;
            return;
        }
        v_pmc_addr_reg = (volatile uint8_t *)(uintptr_t)vaddr;
        v_pmc_data_reg = (volatile uint8_t *)(uintptr_t)vaddr + 1;
        watchdog_available = 1;
    }
}
Пример #6
0
void
map_wellknown_devices()
{
    struct wkdevice *wkp;
    phandle_t	ieeprom;
    pnode_t	root;
    uint_t	stick_freq;

    /*
     * if there is a chosen eeprom, note it (for have_eeprom())
     */
    if (GETPROPLEN(prom_chosennode(), CHOSEN_EEPROM) ==
            sizeof (phandle_t) &&
            GETPROP(prom_chosennode(), CHOSEN_EEPROM, (caddr_t)&ieeprom) != -1)
        chosen_eeprom = (pnode_t)prom_decode_int(ieeprom);

    root = prom_nextnode((pnode_t)0);
    /*
     * Get System clock frequency from root node if it exists.
     */
    if (GETPROP(root, "stick-frequency", (caddr_t)&stick_freq) != -1)
        system_clock_freq = stick_freq;

    map_wellknown(NEXT((pnode_t)0));

    /*
     * See if it worked
     */
    for (wkp = wkdevice; wkp->wk_namep; ++wkp) {
        if (wkp->wk_flags == V_MUSTHAVE) {
            cmn_err(CE_PANIC, "map_wellknown_devices: required "
                    "device %s not mapped", wkp->wk_namep);
        }
    }

    /*
     * all sun4u systems must have an IO bus, i.e. sbus or pcibus
     */
    if (niobus == 0)
        cmn_err(CE_PANIC, "map_wellknown_devices: no i/o bus node");

    check_cpus_ver();
    check_cpus_set();
}
Пример #7
0
static void
have_rtc(pnode_t node)
{
    int size;
    uint32_t eaddr;

    /*
     * "ds1287" module will be selected based on finding a "model"
     * property value of "ds1287" in the "rtc" node.
     */
    if (tod_module_name == NULL) {
        char buf[MAXSYSNAME];

        if (GETPROP(node, "model", buf) != -1) {
            if ((strcmp(buf, "m5819p") == 0) ||
                    (strcmp(buf, "m5823") == 0))
                tod_module_name = "todm5823";
            else if (strcmp(buf, "ds1287") == 0)
                tod_module_name = "todds1287";
        }
    }

    /*
     * XXX - drives on if address prop doesn't exist, later falls
     * over in tod module
     */
    if ((size = GETPROPLEN(node, OBP_ADDRESS)) == -1)
        return;
    if (size != sizeof (eaddr))
        cmn_err(CE_PANIC, "rtc addr size");
    if (GETPROP(node, OBP_ADDRESS, (caddr_t)&eaddr) == -1)
        cmn_err(CE_PANIC, "rtc addr");

    v_rtc_addr_reg = (caddr_t)(uintptr_t)eaddr;
    v_rtc_data_reg = (volatile unsigned char *)(uintptr_t)eaddr + 1;

    /*
     * Does this rtc have watchdog support?
     */
    if (GETPROPLEN(node, WATCHDOG_ENABLE) != -1)
        watchdog_available = 1;
}
Пример #8
0
int
get_portid(pnode_t node, pnode_t *cmpp)
{
    int portid;
    int i;
    char dev_type[OBP_MAXPROPNAME];
    pnode_t cpu_parent;

    if (cmpp != NULL)
        *cmpp = OBP_NONODE;

    if (GETPROP(node, "portid", (caddr_t)&portid) != -1)
        return (portid);
    if (GETPROP(node, "upa-portid", (caddr_t)&portid) != -1)
        return (portid);
    if (GETPROP(node, "device_type", (caddr_t)&dev_type) == -1)
        return (-1);

    /*
     * For a virtual cpu node that is a CMP core, the "portid"
     * is in the parent node.
     * For a virtual cpu node that is a CMT strand, the "portid" is
     * in its grandparent node.
     * So we iterate up as far as 2 levels to get the "portid".
     */
    if (strcmp(dev_type, "cpu") == 0) {
        cpu_parent = node = prom_parentnode(node);
        for (i = 0; i < 2; i++) {
            if (node == OBP_NONODE || node == OBP_BADNODE)
                break;
            if (GETPROP(node, "portid", (caddr_t)&portid) != -1) {
                if (cmpp != NULL)
                    *cmpp = cpu_parent;
                return (portid);
            }
            node = prom_parentnode(node);
        }
    }

    return (-1);
}
Пример #9
0
static void
have_tod(pnode_t node)
{
    static char tod_name[MAXSYSNAME];

    if (GETPROP(node, OBP_NAME, (caddr_t)tod_name) == -1)
        cmn_err(CE_PANIC, "tod name");
    /*
     * This is a node with "device_type" property value of "tod".
     * Name of the tod module is the name from the node.
     */
    tod_module_name = tod_name;
}
Пример #10
0
static void
fill_address(pnode_t curnode, char *namep)
{
    struct wkdevice *wkp;
    int size;
    uint32_t vaddr;

    for (wkp = wkdevice; wkp->wk_namep; ++wkp) {
        if (strcmp(wkp->wk_namep, namep) != 0)
            continue;
        if (wkp->wk_flags == V_MAPPED)
            return;
        if (wkp->wk_vaddrp != NULL) {
            if ((size = GETPROPLEN(curnode, OBP_ADDRESS)) == -1) {
                cmn_err(CE_CONT, "device %s size %d\n",
                        namep, size);
                continue;
            }
            if (size != sizeof (vaddr)) {
                cmn_err(CE_CONT, "device %s address prop too "
                        "big\n", namep);
                continue;
            }
            if (GETPROP(curnode, OBP_ADDRESS,
                        (caddr_t)&vaddr) == -1) {
                cmn_err(CE_CONT, "device %s not mapped\n",
                        namep);
                continue;
            }

            /* make into a native pointer */
            *wkp->wk_vaddrp = (caddr_t)(uintptr_t)vaddr;
#ifdef VPRINTF
            VPRINTF("fill_address: %s mapped to %p\n", namep,
                    (void *)*wkp->wk_vaddrp);
#endif /* VPRINTF */
        }
        if (wkp->wk_func != NULL)
            (*wkp->wk_func)(curnode);
        /*
         * If this one is optional and there may be more than
         * one, don't set V_MAPPED, which would cause us to skip it
         * next time around
         */
        if (wkp->wk_flags != V_MULTI)
            wkp->wk_flags = V_MAPPED;
    }
}
Пример #11
0
/*
 * The first sysio must always programmed up for the system clock and error
 * handling purposes, referenced by v_sysio_addr in machdep.c.
 */
static void
have_sbus(pnode_t node)
{
    int size;
    uint_t portid;

    size = GETPROPLEN(node, "upa-portid");
    if (size == -1 || size > sizeof (portid))
        cmn_err(CE_PANIC, "upa-portid size");
    if (GETPROP(node, "upa-portid", (caddr_t)&portid) == -1)
        cmn_err(CE_PANIC, "upa-portid");

    niobus++;

    /*
     * need one physical TSB
     */
    niommu_tsbs++;
}
Пример #12
0
void
fill_cpu(pnode_t node)
{
    extern int cpu_get_cpu_unum(int, char *, int, int *);
    struct cpu_node *cpunode;
    processorid_t cpuid;
    int portid;
    int tlbsize;
    int size;
    uint_t clk_freq;
    pnode_t cmpnode;
    char namebuf[OBP_MAXPROPNAME], unum[UNUM_NAMLEN];
    char *namebufp;
    int proplen;

    if ((portid = get_portid(node, &cmpnode)) == -1) {
        cmn_err(CE_PANIC, "portid not found");
    }

    if (GETPROP(node, "cpuid", (caddr_t)&cpuid) == -1) {
        cpuid = portid;
    }

    if (cpuid < 0 || cpuid >= NCPU) {
        cmn_err(CE_PANIC, "cpu node %x: cpuid %d out of range", node,
                cpuid);
        return;
    }

    cpunode = &cpunodes[cpuid];
    cpunode->portid = portid;
    cpunode->nodeid = node;

    if (cpu_get_cpu_unum(cpuid, unum, UNUM_NAMLEN, &size) != 0) {
        cpunode->fru_fmri[0] = '\0';
    } else {
        (void) snprintf(cpunode->fru_fmri, sizeof (cpunode->fru_fmri),
                        "%s%s", CPU_FRU_FMRI, unum);
    }

    if (cmpnode) {
        /*
         * For the CMT case, the parent "core" node contains
         * properties needed below, use it instead of the
         * cpu node.
         */
        if ((GETPROP(cmpnode, "device_type", namebuf) > 0) &&
                (strcmp(namebuf, "core") == 0)) {
            node = cmpnode;
        }
    }

    (void) GETPROP(node, (cmpnode ? "compatible" : "name"), namebuf);

    /* Make sure CPU name is within boundary and NULL terminated */
    proplen = GETPROPLEN(node, (cmpnode ? "compatible" : "name"));
    ASSERT(proplen > 0 && proplen <= OBP_MAXPROPNAME);

    if (proplen >= OBP_MAXPROPNAME)
        proplen = OBP_MAXPROPNAME - 1;

    namebuf[proplen] = '\0';

    namebufp = namebuf;
    if (strncmp(namebufp, "SUNW,", 5) == 0)
        namebufp += 5;
    else if (strncmp(namebufp, "FJSV,", 5) == 0)
        namebufp += 5;
    (void) strcpy(cpunode->name, namebufp);

    (void) GETPROP(node, "implementation#",
                   (caddr_t)&cpunode->implementation);
    (void) GETPROP(node, "mask#", (caddr_t)&cpunode->version);

    if (IS_CHEETAH(cpunode->implementation)) {
        /* remap mask reg */
        cpunode->version = REMAP_CHEETAH_MASK(cpunode->version);
    }
    if (GETPROP(node, "clock-frequency", (caddr_t)&clk_freq) == -1) {
        /*
         * If we didn't find it in the CPU node, look in the root node.
         */
        pnode_t root = prom_nextnode((pnode_t)0);
        if (GETPROP(root, "clock-frequency", (caddr_t)&clk_freq) == -1)
            clk_freq = 0;
    }
    cpunode->clock_freq = clk_freq;

    ASSERT(cpunode->clock_freq != 0);
    /*
     * Compute scaling factor based on rate of %tick. This is used
     * to convert from ticks derived from %tick to nanoseconds. See
     * comment in sun4u/sys/clock.h for details.
     */
    cpunode->tick_nsec_scale = (uint_t)(((uint64_t)NANOSEC <<
                                         (32 - TICK_NSEC_SHIFT)) / cpunode->clock_freq);

    (void) GETPROP(node, "#itlb-entries", (caddr_t)&tlbsize);
    ASSERT(tlbsize < USHRT_MAX); /* since we cast it */
    cpunode->itlb_size = (ushort_t)tlbsize;

    (void) GETPROP(node, "#dtlb-entries", (caddr_t)&tlbsize);
    ASSERT(tlbsize < USHRT_MAX); /* since we cast it */
    cpunode->dtlb_size = (ushort_t)tlbsize;

    if (cmpnode != OBP_NONODE) {
        /*
         * If the CPU has a level 3 cache, then it will be the
         * external cache. Otherwise the level 2 cache is the
         * external cache.
         */
        size = 0;
        (void) GETPROP(node, "l3-cache-size", (caddr_t)&size);
        if (size <= 0)
            (void) GETPROP(node, "l2-cache-size", (caddr_t)&size);
        ASSERT(size != 0);
        cpunode->ecache_size = size;

        size = 0;
        (void) GETPROP(node, "l3-cache-line-size", (caddr_t)&size);
        if (size <= 0)
            (void) GETPROP(node, "l2-cache-line-size",
                           (caddr_t)&size);
        ASSERT(size != 0);
        cpunode->ecache_linesize = size;

        size = 0;
        (void) GETPROP(node, "l2-cache-associativity", (caddr_t)&size);
        ASSERT(size != 0);
        cpunode->ecache_associativity = size;

        cmp_add_cpu(portid, cpuid);
    } else {
        size = 0;
        (void) GETPROP(node, "ecache-size", (caddr_t)&size);
        ASSERT(size != 0);
        cpunode->ecache_size = size;

        size = 0;
        (void) GETPROP(node, "ecache-line-size", (caddr_t)&size);
        ASSERT(size != 0);
        cpunode->ecache_linesize = size;

        size = 0;
        (void) GETPROP(node, "ecache-associativity", (caddr_t)&size);
        ASSERT(size != 0);
        cpunode->ecache_associativity = size;
    }

    /* by default set msram to non-mirrored one */
    cpunode->msram = ECACHE_CPU_NON_MIRROR;

    if (GETPROPLEN(node, "msram") != -1) {
        cpunode->msram = ECACHE_CPU_MIRROR;
    }

    if (GETPROPLEN(node, "msram-observed") != -1) {
        cpunode->msram = ECACHE_CPU_MIRROR;
    }

    if (ncpunode == 0) {
        cpu_fiximp(node);
    }

    cpunode->ecache_setsize =
        cpunode->ecache_size / cpunode->ecache_associativity;

    adj_ecache_setsize(cpunode->ecache_setsize);

    ncpunode++;
}
Пример #13
0
/*
 * map_wellknown - map known devices & registers
 */
static void
map_wellknown(pnode_t curnode)
{
    extern int status_okay(int, char *, int);
    char tmp_name[MAXSYSNAME];
    int sok;

#ifdef VPRINTF
    VPRINTF("map_wellknown(%x)\n", curnode);
#endif /* VPRINTF */

    for (curnode = CHILD(curnode); curnode; curnode = NEXT(curnode)) {
        /*
         * prune subtree if status property indicating not okay
         */
        sok = status_okay((int)curnode, (char *)NULL, 0);
        if (!sok) {
            char devtype_buf[OBP_MAXPROPNAME];
            int size;

#ifdef VPRINTF
            VPRINTF("map_wellknown: !okay status property\n");
#endif /* VPRINTF */
            /*
             * a status property indicating bad memory will be
             * associated with a node which has a "device_type"
             * property with a value of "memory-controller"
             */
            if ((size = GETPROPLEN(curnode,
                                   OBP_DEVICETYPE)) == -1)
                continue;
            if (size > OBP_MAXPROPNAME) {
                cmn_err(CE_CONT, "node %x '%s' prop too "
                        "big\n", curnode, OBP_DEVICETYPE);
                continue;
            }
            if (GETPROP(curnode, OBP_DEVICETYPE,
                        devtype_buf) == -1) {
                cmn_err(CE_CONT, "node %x '%s' get failed\n",
                        curnode, OBP_DEVICETYPE);
                continue;
            }
            if (strcmp(devtype_buf, "memory-controller") != 0)
                continue;
            /*
             * ...else fall thru and process the node...
             */
        }
        bzero(tmp_name, MAXSYSNAME);
        if (GETPROP(curnode, OBP_NAME, (caddr_t)tmp_name) != -1)
            fill_address(curnode, tmp_name);
        if (GETPROP(curnode, OBP_DEVICETYPE, tmp_name) != -1 &&
                strcmp(tmp_name, "cpu") == 0) {
            fill_cpu(curnode);
        }
        if (strcmp(tmp_name, "tod") == 0)
            have_tod(curnode);
        if (sok && (strcmp(tmp_name, "memory-controller") == 0) &&
                (&plat_fill_mc != NULL))
            plat_fill_mc(curnode);
        map_wellknown(curnode);
    }
}