示例#1
0
文件: eth.c 项目: 1tgr/mobius
static void EthHandleBinding(void)
{
    net_binding_t *bind;
    request_eth_t req_eth;

    union
    {
        uint8_t raw[ETH_FRAME_LEN];
        net_ether header;
    } packet;

    page_array_t *pages;
    io_callback_t cb;
    event_t *event;
    net_hwaddr_t src, dst;

    bind = ThrGetCurrent()->info->param;

    pages = MemCreatePageArray(packet.raw, sizeof(packet.raw));
    event = EvtCreate(false);
    src.type = dst.type = NET_HW_ETHERNET;
    src.data_size = dst.data_size = 6;

    while (true)
    {
        req_eth.header.code = ETH_RECEIVE;
        req_eth.header.param = (void*) event;
        memcpy(req_eth.params.eth_receive.from, bcast, sizeof(bcast));
        req_eth.params.eth_receive.type = (uint16_t) (addr_t) bind->hw_cookie;
        req_eth.params.eth_receive.pages = pages;
        req_eth.params.eth_receive.length = sizeof(packet.raw);
        cb.type = IO_CALLBACK_FUNCTION;
        cb.u.function = EthHandleBindingCompletion;

        if (!IoRequest(&cb, bind->dev, &req_eth.header))
        {
            wprintf(L"EthHandleBinding: IoRequest error\n");
            break;
        }

        ThrWaitHandle(ThrGetCurrent(), &event->hdr);
        KeYield();

        memcpy(src.u.ethernet, packet.header.src, sizeof(src.u.ethernet));
        memcpy(dst.u.ethernet, packet.header.dst, sizeof(dst.u.ethernet));
        if (bind->proto->vtbl->receive_packet != NULL)
            bind->proto->vtbl->receive_packet(bind->proto, 
                bind, &src, &dst, 
                packet.raw + sizeof(packet.header),
                req_eth.params.eth_receive.length - sizeof(packet.header));
    }

    HndClose(&event->hdr);
    ThrExitThread(0);
    KeYield();
}
示例#2
0
bool IoAlcorFirmware::GetVersion(uint16_t& out_version)
{
    const Operation inst(Op::Version);
    Operation outbuf;

    if(IoRequest(inst, outbuf) && IoWaitRequestOutput4(inst, outbuf))
    {
        out_version = outbuf.Out0<uint16_t>();
        return true;
    }
    return false;
}
示例#3
0
bool IoAlcorFirmware::FlashTellSuccessProgramming()
{
    const Operation inst_program(Op::Program, true, 0, 0);
    Operation outbuf;

    // XXX weirdly CoolerMaster does [something like] IoRequest in a loop here until it acks instead of IoWait'ing.
    if(IoRequest(inst_program, outbuf) && IoWaitRequestOutput4(inst_program, outbuf))
    {
        return (outbuf.out[0] & outbuf.out[1] & outbuf.out[2] & outbuf.out[3]) == success_request;
    }
    return false;
}
示例#4
0
bool IoAlcorFirmware::GetNumber2(uint32_t& out_2)
{
    const Operation inst(Op::Return2);
    Operation outbuf;

    if(IoRequest(inst, outbuf) && IoWaitRequestOutput4(inst, outbuf))
    {
        out_2 = outbuf.Out0<uint32_t>();
        return true;
    }
    return false;
}
示例#5
0
bool IoAlcorFirmware::FlashProgram(uint32_t begin, uint32_t end, void* datav, uint16_t& out_datav_checksum)
{
    const Operation inst_program(Op::Program, false, begin, end);
    Operation outbuf;
    uint8_t* data = (uint8_t*)(datav);

    out_datav_checksum = 0;

    // Ensure range is correct.
    if(begin > end)
        return false;

    // Ensure word alignment on begin, and one byte before alignment on end.
    if((begin % 4) != 0 || (end % 4) != 3)
        return false;

    // For security reasons only allow flashing the user settings area.
    if(begin >= 0xD800 && end <= 0x1F7FF)
    {
        if(IoRequest(inst_program, outbuf) && IoWaitRequestOutput4(inst_program, outbuf))
        {
            if((outbuf.out[0] & outbuf.out[1] & outbuf.out[2] & outbuf.out[3]) == success_request)
            {
                for(uint32_t addr = begin; addr < end; addr += bytes_step)
                {
                    // We need a temporary buffer because of report id on the first byte
                    uint8_t buffer[feature_size];
                    auto left = (end - addr) + 1;
                    auto it_bytes = (std::min)(left, bytes_step);
                    std::memset(buffer, 0, feature_size); // necessary because next memcpy mayn't copy feature_size due to std::min
                    std::memcpy(&buffer[1], &data[addr - begin], it_bytes);

                    for(uint32_t idsum = 0; idsum < it_bytes; ++idsum)
                    {
                        if((addr + idsum != 0xD800) && (addr + idsum != 0xD801))
                        {
                            out_datav_checksum += buffer[idsum+1]; // (+1 to skip report id)
                        }
                    }

                    if(!IoBytesInput(inst_program, buffer, feature_size))
                        return false;
                }
                return true;
            }
        }
    }

    return false;
}
示例#6
0
bool IoAlcorFirmware::IoEnableUnsafe(bool enable)
{
    const Operation inst(Op::EnableUnsafe, uint32_t(enable? 0x29156767 : 0x0));
    Operation outbuf;

    if(IoRequest(inst, outbuf) && IoWaitRequestOutput4(inst, outbuf))
    {
        if(enable)
            return ((outbuf.out[0] & outbuf.out[1] & outbuf.out[2] & outbuf.out[3]) == success_request);
        else
            return ((outbuf.out[0] & outbuf.out[1] & outbuf.out[2] & outbuf.out[3]) == failed_request);
    }

    return false;
}
示例#7
0
bool IoAlcorFirmware::MemoryRead(uint32_t begin, uint32_t end, void* dataoutv)
{
    const Operation inst_trigger(Op::ReadBytes, begin, end);
    Operation outbuf;
    uint8_t* dataout = (uint8_t*)(dataoutv);

    // Ensure range is correct.
    if(begin > end)
        return false;

    // Ensure word alignment on begin, and one byte before alignment on end.
    if((begin % 4) != 0 || (end % 4) != 3)
        return false;

    // Ensure the memory won't segfault during writing, if it is to segfault when reading from
    // the mouse memory, bad things may happen.
    std::memset(dataoutv, 0, (end - begin) + 1);

    if(IoRequest(inst_trigger, outbuf) && IoWaitRequestOutput4(inst_trigger, outbuf))
    {
        if((outbuf.out[0] & outbuf.out[1] & outbuf.out[2] & outbuf.out[3]) == success_request)
        {
            static_assert(bytes_step + 1 == feature_size, "");

            for(uint32_t addr = begin; addr < end; addr += bytes_step)
            {
                // We need a temporary buffer because of report id on the first byte
                uint8_t buffer[feature_size];
                if(!IoBytesOutput(buffer, feature_size))
                    return false;

                auto left = (end - addr) + 1;
                std::memcpy(&dataout[addr - begin], &buffer[1], (std::min)(left, bytes_step));
            }

            return true;
        }
    }
    return false;
}
示例#8
0
bool IoAlcorFirmware::FlashErasePages(uint32_t begin, uint32_t end)
{
    const Operation inst_erase(Op::Erase, begin, end);
    Operation outbuf;

    // Ensure range is correct.
    if(begin > end)
        return false;

    // Ensure word alignment on begin, and one byte before alignment on end.
    if((begin % 4) != 0 || (end % 4) != 3)
        return false;

    // For security reasons only allow flashing the user settings area.
    if(begin >= 0xD800 && end <= 0x1F7FF)
    {
        if(IoRequest(inst_erase, outbuf) && IoWaitRequestOutput4(inst_erase, outbuf))
        {
            return ((outbuf.out[0] & outbuf.out[1] & outbuf.out[2] & outbuf.out[3]) == success_request);
        }
    }

    return false;
}
示例#9
0
bool IoAlcorFirmware::Checksum(uint32_t begin, uint32_t end, uint16_t& out_checksum)
{
    const Operation inst_checksum(Op::Checksum, begin, end);
    Operation outbuf;

    // Ensure range is correct.
    if(begin > end)
        return false;

    // Ensure word alignment on begin, and one byte before alignment on end.
    if((begin % 4) != 0 || (end % 4) != 3)
        return false;

    if(IoRequest(inst_checksum, outbuf) && IoWaitRequestOutput2(inst_checksum, outbuf))
    {
        if((outbuf.out[0] & outbuf.out[1]) == success_request)
        {
            out_checksum = outbuf.Out2<uint16_t>();
            return true;
        }
    }

    return false;
}
示例#10
0
文件: cdfs.c 项目: 1tgr/mobius
status_t CdfsReadWriteFile(fsd_t *fsd, const fs_request_t *req, size_t *bytes)
{
	cdfs_t *cdfs;
    cdnode_t *cdnode;
	io_callback_t cb;
	request_dev_t *dev_request;
	int length;
	uint32_t aligned_file_length;

	cdfs = (cdfs_t*) fsd;
    cdnode = req->file->fsd_cookie;

	//wprintf(L"CdfsReadWriteFile(%x): %u bytes at %u\n",
		//cdnode->id, req->length, (unsigned) req->pos);

	if (!req->is_reading)
	{
		wprintf(L"CdfsReadWriteFile: read-only\n");
		return EACCESS;
	}

	aligned_file_length = (cdnode->entry.length.native + SECTOR_SIZE - 1) & -SECTOR_SIZE;
	if (req->pos >= aligned_file_length)
	{
		wprintf(L"CdfsReadWriteFile: read past end of file (aligned_file_length = %u)\n",
			aligned_file_length);
		return EEOF;
	}

	if (req->pos + req->length >= aligned_file_length)
		length = aligned_file_length - req->pos;
	else
		length = req->length;

	assert((req->pos & (SECTOR_SIZE - 1)) == 0);
	assert((length & (SECTOR_SIZE - 1)) == 0);
	assert(length == SECTOR_SIZE);

	dev_request = malloc(sizeof(*dev_request));
	if (dev_request == NULL)
		return errno;

    dev_request->header.code = DEV_READ;
    dev_request->params.buffered.pages = req->pages;
    dev_request->params.buffered.length = length;
    dev_request->params.buffered.offset = 
		cdnode->entry.first_sector.native * SECTOR_SIZE + 
		req->pos;
    dev_request->header.param = req->io;

	//wprintf(L"\t=> %u bytes at 0x%x\n", 
		//dev_request->params.buffered.length, 
		//dev_request->params.buffered.offset);

    cb.type = IO_CALLBACK_FSD;
    cb.u.fsd = &cdfs->fsd;
    if (!IoRequest(&cb, cdfs->device, &dev_request->header))
    {
		status_t ret;
        wprintf(L"CdfsReadWriteFile: request failed straight away\n");
        *bytes = dev_request->params.buffered.length;
		ret = dev_request->header.result;
		free(dev_request);
		return ret;
    }

	return SIOPENDING;
}