static int rtas_gettime(device_t dev, struct timespec *ts) { struct clocktime ct; cell_t tod[8]; cell_t token; int error; token = rtas_token_lookup("get-time-of-day"); if (token == -1) return (ENXIO); error = rtas_call_method(token, 0, 8, &tod[0], &tod[1], &tod[2], &tod[3], &tod[4], &tod[5], &tod[6], &tod[7]); if (error < 0) return (ENXIO); if (tod[0] != 0) return ((tod[0] == -1) ? ENXIO : EAGAIN); ct.year = tod[1]; ct.mon = tod[2]; ct.day = tod[3]; ct.hour = tod[4]; ct.min = tod[5]; ct.sec = tod[6]; ct.nsec = tod[7]; return (clock_ct_to_ts(&ct, ts)); }
static void rtas_shutdown(void *arg, int howto) { cell_t token, status; if (howto & RB_HALT) { token = rtas_token_lookup("power-off"); if (token == -1) return; rtas_call_method(token, 2, 1, 0, 0, &status); } else { token = rtas_token_lookup("system-reboot"); if (token == -1) return; rtas_call_method(token, 0, 1, &status); } }
static uint32_t rtaspci_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, int width) { struct rtaspci_softc *sc; uint32_t retval = 0xffffffff; uint32_t config_addr; int error, pcierror; sc = device_get_softc(dev); config_addr = ((bus & 0xff) << 16) | ((slot & 0x1f) << 11) | ((func & 0x7) << 8) | (reg & 0xff); if (sc->sc_extended_config) config_addr |= (reg & 0xf00) << 16; if (sc->ex_read_pci_config != -1) error = rtas_call_method(sc->ex_read_pci_config, 4, 2, config_addr, sc->sc_pcir.phys_hi, sc->sc_pcir.phys_mid, width, &pcierror, &retval); else error = rtas_call_method(sc->read_pci_config, 2, 2, config_addr, width, &pcierror, &retval); /* Sign-extend output */ switch (width) { case 1: retval = (int32_t)(int8_t)(retval); break; case 2: retval = (int32_t)(int16_t)(retval); break; } if (error < 0 || pcierror != 0) retval = 0xffffffff; return (retval); }
static void rtaspci_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, uint32_t val, int width) { struct rtaspci_softc *sc; uint32_t config_addr; int pcierror; sc = device_get_softc(dev); config_addr = ((bus & 0xff) << 16) | ((slot & 0x1f) << 11) | ((func & 0x7) << 8) | (reg & 0xff); if (sc->sc_extended_config) config_addr |= (reg & 0xf00) << 16; if (sc->ex_write_pci_config != -1) rtas_call_method(sc->ex_write_pci_config, 5, 1, config_addr, sc->sc_pcir.phys_hi, sc->sc_pcir.phys_mid, width, val, &pcierror); else rtas_call_method(sc->write_pci_config, 3, 1, config_addr, width, val, &pcierror); }
static int rtas_settime(device_t dev, struct timespec *ts) { struct clocktime ct; cell_t token, status; int error; token = rtas_token_lookup("set-time-of-day"); if (token == -1) return (ENXIO); clock_ts_to_ct(ts, &ct); error = rtas_call_method(token, 7, 1, ct.year, ct.mon, ct.day, ct.hour, ct.min, ct.sec, ct.nsec, &status); if (error < 0) return (ENXIO); if (status != 0) return (((int)status < 0) ? ENXIO : EAGAIN); return (0); }
static int chrp_smp_start_cpu(platform_t plat, struct pcpu *pc) { cell_t start_cpu; int result, err, timeout; if (!rtas_exists()) { printf("RTAS uninitialized: unable to start AP %d\n", pc->pc_cpuid); return (ENXIO); } start_cpu = rtas_token_lookup("start-cpu"); if (start_cpu == -1) { printf("RTAS unknown method: unable to start AP %d\n", pc->pc_cpuid); return (ENXIO); } ap_pcpu = pc; powerpc_sync(); result = rtas_call_method(start_cpu, 3, 1, pc->pc_cpuid, EXC_RST, pc, &err); if (result < 0 || err != 0) { printf("RTAS error (%d/%d): unable to start AP %d\n", result, err, pc->pc_cpuid); return (ENXIO); } timeout = 10000; while (!pc->pc_awake && timeout--) DELAY(100); return ((pc->pc_awake) ? 0 : EBUSY); }