/** * Bit shift the data out * * \param data: input data * \return Received data */ uint8_t BbspiClass::transfer(uint8_t data) { uint8_t recv_data = 0; pioWrite(bb_clk, bb_cpol); pioWrite(bb_mosi, 0); for (int i = 0; i < 8; i++) { recv_data = recv_data << 1; if (data > 127) pioWrite(bb_mosi, 1); else pioWrite(bb_mosi, 0); pioWrite(bb_clk, !bb_cpol); if (bb_cpha == 0) recv_data |= pioRead(bb_miso); data = data << 1; pioWrite(bb_clk, bb_cpol); if (bb_cpha == 1) recv_data |= pioRead(bb_miso); } return recv_data; }
bool X86AtaDevice::performPioAtapiOperation(const AtapiCommand &cmd, uint16_t *buf, size_t bufSize) const { uint8_t status = 0; // Set PIO outb(_ioPort + kAtaRegisterFeatureInfo, 0x00); // set maximum size for requested data outb(_ioPort + kAtaRegisterLbaMid, static_cast<uint8_t>(bufSize & 0xFF)); outb(_ioPort + kAtaRegisterLbaHigh, static_cast<uint8_t>(bufSize >> 8)); // send PACKET cmd outb(_ioPort + kAtaRegisterCommand, 0xA0); // poll while (1) { status = inb(_ioPort + kAtaRegisterStatus); if ((status & kAtaStatusBitError)) { puts("ATAPI early error; unsure"); return false; } if (!(status & kAtaStatusBitBusy) && (status & kAtaStatusBitReady)) break; } // send the ATAPI command packet for (int i = 0; i < 6; ++i) { outw(_ioPort, cmd.packet().words[i]); } // poll while (1) { status = inb(_ioPort + kAtaRegisterStatus); if ((status & kAtaStatusBitError)) { puts("ATAPI error; no medium?"); return false; } if (!(status & kAtaStatusBitBusy) && (status & kAtaStatusBitReady)) break; if ((status & kAtaStatusBitDRQ)) break; } // check if there's data to read if ((status & kAtaStatusBitDRQ)) { // get actual size of data. We could optimize our buffer size a bit here, but whatever. uint16_t readSizeBytes = inb(_ioPort + kAtaRegisterLbaHigh) << 8; readSizeBytes = readSizeBytes | inb(_ioPort + kAtaRegisterLbaMid); pioRead(buf, readSizeBytes); } else if (bufSize) { puts("No data to read but we made a buffer. Really makes you think..."); } return true; }
void X86AtaDevice::identify() const { // Set features register. 0 = PIO, 1 = DMA. outb(_ioPort + 1, 0); outb(_controlPort, 0); // select device outb(_ioPort + kAtaRegisterDriveSelect, 0xA0 | _slaveBit << 4); ioWait(); switch (type()) { case Type::PATAPI: case Type::SATAPI: // send IDENTIFY PACKET DEVICE outb(_ioPort + 0x07, 0xA1); break; case Type::PATA: case Type::SATA: // send IDENTIFY DEVICE outb(_ioPort + 0x07, 0xEC); break; case Type::Unknown: return; } ioWait(); // read in status waitUntilReady(false); // read in device information uint16_t identity[256]; pioRead(identity, 256); _descriptor.readIdentity(identity); _identified = true; if (type() == Type::PATAPI) { uint16_t data[4]; performPioAtapiOperation(AtapiCommand::readCapacityCommand(), data, sizeof(data)); _descriptor.readAtapiCapacity(data); } }
int gptReadNext(GPTServer* server, PIODatatype datatype, void** buffer, int* nLabels, int** labels) { int number = -1; int numberOfLabels = -1; int i, r; if (!DAT_AVAILABLE(*server)) { server->eof = 1; return -1; } // if last timerange is processed, go to first timerange of next file if (server->current_timerange_index == DAT_NTIMERANGES(*server, server->current_file_index)) { if (PIODatasetIsValid(server->current_dataset)) pioCloseDataset(&(server->current_dataset)); if (PIOFileIsValid(server->current_file)) pioCloseFile(&(server->current_file)); server->current_timerange_index = 0; server->current_file_index++; } // if last file is processed, stop if (server->current_file_index == DAT_NFILES(*server)) { server->current_file_index = 0; server->current_timerange_index = 0; server->eof = 1; return -1; } // open next file/dataset if necessary if (server->current_timerange_index == 0) { server->current_file = pioOpenFile(DAT_PATH(*server, server->current_file_index), PINOCCHIO_READONLY); server->current_dataset = pioOpenDataset(PIOMakeObject(server->current_file), DAT_DATASET(*server)); } // if not filtered, read next data if (DAT_FILTERED(*server, server->current_file_index, server->current_timerange_index)) { number = pioRead(&(server->current_dataset), server->current_timerange_index, datatype, buffer); // get total number of corresponding labels // (as the sum of number of labels for each corresponding timeranges) if (nLabels || labels) { if (LBL_AVAILABLE(*server)) { numberOfLabels = 0; for (i=0; i<server->numberOfCorrespondingLabelTimerange[server->current_file_index][server->current_timerange_index]; i++) { numberOfLabels += LBL_NLABELS(*server, server->current_file_index, i+server->firstCorrespondingLabelTimerange[server->current_file_index][server->current_timerange_index]); } } } if (nLabels) { if (LBL_AVAILABLE(*server)) *nLabels = numberOfLabels; else *nLabels = 0; } if (labels) { if (LBL_AVAILABLE(*server)) { if (numberOfLabels > server->current_data_labels_number) { server->current_data_labels_number = numberOfLabels; server->current_data_labels = (int*) realloc(server->current_data_labels, server->current_data_labels_number*sizeof(int)); } numberOfLabels = 0; for (i=0; i<server->numberOfCorrespondingLabelTimerange[server->current_file_index][server->current_timerange_index]; i++) { for (r=0; r<LBL_NLABELS(*server, server->current_file_index, i+server->firstCorrespondingLabelTimerange[server->current_file_index][server->current_timerange_index]); r++) { server->current_data_labels[numberOfLabels] = LBL_LABEL(*server, server->current_file_index, i+server->firstCorrespondingLabelTimerange[server->current_file_index][server->current_timerange_index], r); numberOfLabels++; } } *labels = server->current_data_labels; } else *labels = NULL; } server->current_timerange_index++; } // otherwise, go to next timerange else { server->current_timerange_index++; number = gptReadNext(server, datatype, buffer, nLabels, labels); } // return number of data return number; }