OK, turing.

<- leave blank

Sat Jun 15 20:22:18 EDT 2019

https://www.youtube.com/user/profyclub/videos

Sat Jun 15 18:08:52 EDT 2019
int
main()
{
  puts("hello, world!");
}

Sat Jun 15 14:00:46 EDT 2019
,x/\(\n.*\n\)$/[\n ]*/d

Sat Jun 15 13:06:55 EDT 2019
typedef struct USBReq USBReq;
typedef struct USBPkt USBPkt;
typedef struct USBQueue USBQueue;
typedef struct USBEp USBEp;

struct USBReq {
	uint8_t bmRequestType;
	uint8_t bRequest;
	uint16_t wValue;
	uint16_t wIndex;
	uint16_t wLength;

	uint16_t ptr, len;
	uint8_t *data;
};

struct USBPkt {
	uint16_t len;
	uint16_t ptr;
	USBPkt *next;
	uint8_t data[0];
};

struct USBQueue {
	USBEp *ep;
	USBPkt *first, **nextp;
	int qalloc, maxq;
};

struct USBEp {
	uint8_t devep;
	uint8_t targep;
	uint16_t fifosz;
	uint16_t fifoad;
	USBQueue *q;
};

extern USBQueue msgq;
extern USBQueue corrq;


Sat Jun 15 13:05:50 EDT 2019
#include <xc.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <sys/attribs.h>
#include <assert.h>
#include "io.h"
#include "dat.h"
#include "fns.h"
#include "usbif.h"
#include "usbdesc.h"

#define dprintf printf

static enum {
	USBRESET,
	USBADDRESS,
	USBCONFIG
} usbstate;
static uint8_t selfpower;
static uint8_t configuration;
enum { MAXCONFIG = 1 };

enum { MAXPKT = 64 };


enum {
	RTTOHOST = 0x80,
	RTTYPE = 0x60,
	RTSTANDARD = 0,
	RTCLASS = 0x20,
	RTVENDOR = 0x40,
	RTRECIP = 0x1f,
	RTRDEVICE = 0,
	RTRIFACE = 1,
	RTRENDP = 2,
	RTROTHER = 3,
};

enum {
	Get_Status = 0,
	Clear_Feature = 1,
	Set_Feature = 3,
	Set_Address = 5,
	Get_Descriptor = 6,
	Set_Descriptor = 7,
	Get_Configuration = 8,
	Set_Configuration = 9,
	Get_Interface = 10,
	Set_Interface = 11,
	Synch_Frame = 12,
};

USBQueue msgq = {.maxq = 4096};
USBQueue corrq = {.maxq = 16384};

USBEp eptx[8], eprx[8];
void (*poststatus)(void);

enum { USBMEMSZ = 1<<12 };
static int
usballoc(int sz)
{
	static int loc = 16;
	int rv;

	if(loc + sz > USBMEMSZ)
		panic("out of USB device memory");
	rv = loc;
	loc += sz;
	return rv;
}

static void
bulkep(int devep, int targep, int mult, USBQueue *queue)
{
	if(devep < 1 || devep >= 8 || (targep & 0x70) != 0){
		printf("bulkep(%d,%#.2x,%d,%p): invalid arguments\n", devep,
		targep, mult, queue);
		return;
	}
	if((targep & 0x80) != 0){
		assert(eptx[devep].targep == 0);
		eptx[devep].devep = devep;
		eptx[devep].targep = targep;
		eptx[devep].fifosz = (mult + 1) * 512;
		eptx[devep].fifoad = usballoc((mult + 1) * (512 / 8));
		eptx[devep].q = queue;
		queue->ep = &eptx[devep];
	}else{
		assert(eprx[devep].targep == 0);
		eprx[devep].devep = devep;
		eprx[devep].targep = targep;
		eprx[devep].fifosz = (mult + 1) * 512;
		eprx[devep].fifoad = usballoc((mult + 1) * (512 / 8));
		eprx[devep].q = queue;
		queue->ep = &eprx[devep];
	}
}

static void
resetep0(void)
{
	USBCSR3bits.ENDPOINT = 0;
	USBE0CSR0 = 0;
	USBFIFOAbits.RXFIFOAD = 0;
	USBFIFOAbits.TXFIFOAD = 8;
	USBOTGbits.TXFIFOSZ = 3;
	USBOTGbits.RXFIFOSZ = 3;
	USBCSR1bits.EP0IE = 1;
}

static void
resetbulkep(USBEp *ep)
{
	int mult, sz, i;

	mult = ep->fifosz / 512 - 1;
	sz = 6;
	for(i = mult + 1; i > 1; i >>= 1)
		sz++;

	USBCSR3bits.ENDPOINT = ep->devep;
	if((ep->targep & 0x80) != 0){
		USBIENCSR0 = mult << 11 | 512;
		USBIENCSR2 = 2 << 20 | (ep->targep & 0xf) << 16;
		USBOTGbits.TXFIFOSZ = sz;
		USBFIFOAbits.TXFIFOAD = ep->fifoad;
		USBCSR1 |= 1<<8 + ep->devep;
	}else{
		USBIENCSR1 = mult << 11 | 512;
		USBIENCSR3 = 1 << 6 | 2 << 4 | ep->targep & 0xf;
		USBOTGbits.RXFIFOSZ = sz;
		USBFIFOAbits.RXFIFOAD = ep->fifoad;
		USBCSR1 |= 1<<ep->devep;
	}
	USBCSR3bits.ENDPOINT = 0;
}

static void
usbreset(void)
{
	int i;

	printf("USB: reset\n");
	usbstate = USBRESET;
	USBCSR0bits.FUNC = 0;
	configuration = 0;

	resetep0();
	for(i = 1; i < 8; i++){
		if(eptx[i].targep != 0)
			resetbulkep(&eptx[i]);
		if(eprx[i].targep != 0)
			resetbulkep(&eprx[i]);
	}
}

static void
ep0stall(void)
{
	dprintf("USB: replying with stall\n");
	USBE0CSR0bits.STALL = 1;
}

static void
mkusbreq(USBReq *r, uint8_t *d)
{
	free(r->data);
	memset(r, 0, sizeof(*r));
	r->bmRequestType = d[0];
	r->bRequest = d[1];
	r->wValue = d[2] | d[3] << 8;
	r->wIndex = d[4] | d[5] << 8;
	r->wLength = d[6] | d[7] << 8;
	if(r->wLength != 0){
		r->data = malloc(r->wLength);
		assert(r->data != NULL);
	}
}

static int
ep0_Get_Configuration(USBReq *r)
{
	dprintf("USB: Get_Configuration()\n");
	if(r->bmRequestType != 0x80 || r->wValue != 0 || r->wIndex != 0
	|| r->wLength != 1)
		return -1;
	r->data[0] = configuration;
	return 1;
}

static void kickall(void);

static int
ep0_Set_Configuration(USBReq *r)
{
	dprintf("USB: Set_Configuration(%d)\n", r->wValue);
	if(r->bmRequestType != 0 || r->wIndex != 0 || r->wLength != 0 ||
	r->wValue > MAXCONFIG)
		return -1;
	configuration = r->wValue;
	if(r->wValue == 0) usbstate = USBADDRESS;
	else{
		usbstate = USBCONFIG;
		kickall();
	}
	return 0;
}

static int
ep0_Get_Descriptor(USBReq *r)
{
	const uint8_t *d;
	int dlen;

	dprintf("USB: Get_Descriptor(%d, %d)\n", r->wValue >> 8,
	r->wValue & 0xff);
	if(r->bmRequestType != 0x80)
		return -1;
	switch(r->wValue){
	case 1 << 8: d = devdesc; dlen = devdesc[0]; break;
	case 2 << 8: d = confdesc; dlen = *(uint16_t*)&confdesc[2]; break;
	case 3 << 8: d = langids; dlen = langids[0]; break;
	case 3 << 8 | 1: d = vendstr; dlen = vendstr[0]; break;
	case 3 << 8 | 2: d = prodstr; dlen = prodstr[0]; break;
	default: return -1;
	}
	if(r->wLength < dlen) dlen = r->wLength;
	memcpy(r->data, d, dlen);
	return dlen;
}

static int
ep0_Get_Interface(USBReq *r)
{
	dprintf("USB: Get_Interface(%d)\n", r->wIndex);
	if(r->bmRequestType != 0x81 || r->wValue != 0 || r->wIndex != 0
	|| r->wLength != 1 || usbstate != USBCONFIG)
		return -1;
	r->data[0] = 0;
	return 1;
}

static int
ep0_Get_Status(USBReq *r)
{
	uint16_t rv;

	dprintf("USB: Get_Status(%d)\n", r->bmRequestType & RTRECIP);
	if((int8_t) r->bmRequestType > -0x7e || r->wValue != 0 ||
	r->wLength != 2)
		return -1;
	switch(r->bmRequestType & RTRECIP){
	case RTRDEVICE:
		if(r->wIndex != 0) return -1;
		rv = selfpower & 1;
		break;
	case RTRIFACE:
		if(r->wIndex != 0) return -1;
		rv = 0;
		break;
	case RTRENDP:
		if(r->wIndex != 0) return -1;
		rv = 0;
		break;
	}
	*(uint16_t*)r->data = rv;
	return 2;
}

static int8_t addrchange;

static void
ep0_Set_Address_Complete(void)
{
	USBCSR0bits.FUNC = addrchange;
	usbstate = USBADDRESS;
}

static int
ep0_Set_Address(USBReq *r)
{
	dprintf("USB: Set_Address(%d)\n", r->wValue);
	if(r->bmRequestType != 0 || r->wIndex != 0 || r->wLength != 0 ||
	(uint16_t)(r->wValue - 1) > 126)
		return -1;
	addrchange = r->wValue;
	poststatus = ep0_Set_Address_Complete;
	return 0;
}

static int
ep0_Program_Mode(USBReq *r)
{
	if(r->bmRequestType != RTVENDOR || r->wIndex != 0 || r->wValue !=
	0 || r->wLength != 0)
		return -1;
	RTCCONbits.CAL = 0x15A;
	poststatus = reboot;
	return 0;
}

typedef int EP0Handler(USBReq *);
static EP0Handler * const ep0stdhandler[] = {
	[Get_Configuration] ep0_Get_Configuration,
	[Set_Configuration] ep0_Set_Configuration,
	[Get_Descriptor] ep0_Get_Descriptor,
	[Get_Interface] ep0_Get_Interface,
	[Get_Status] ep0_Get_Status,
	[Set_Address] ep0_Set_Address
};

EP0Handler ep0_qspi_status, ep0_qspi_erase, ep0_qspi_program, ep0_qspi_read,
ep0_Send_Cmd, ep0_Cmd_Status, ep0_Corr_Data, ep0_FPGA_Read, ep0_FPGA_Write,
ep0_Raw_Start, ep0_Raw_Stop;
static EP0Handler * const ep0vhandler[] = {
	[Send_Cmd] ep0_Send_Cmd,
	[Cmd_Status] ep0_Cmd_Status,
	[Corr_Data] ep0_Corr_Data,
	[FPGA_Read] ep0_FPGA_Read,
	[FPGA_Write] ep0_FPGA_Write,
	[QSPI_Status] ep0_qspi_status,
	[QSPI_Erase] ep0_qspi_erase,
	[QSPI_Program] ep0_qspi_program,
	[QSPI_Read] ep0_qspi_read,
	[Program_Mode] ep0_Program_Mode,
	[Raw_Start] ep0_Raw_Start,
	[Raw_Stop] ep0_Raw_Stop
};

static int
ep0req(USBReq *r)
{
	dprintf("USB: bmRequestType=%.2x bRequest=%.2x wValue=%.4x wIndex=%.4x
	wLength=%.4x\n", r->bmRequestType, r->bRequest, r->wValue,
	r->wIndex, r->wLength);
	switch(r->bmRequestType & RTTYPE){
	case RTSTANDARD:
		if(r->bRequest >= nelem(ep0stdhandler) ||
		ep0stdhandler[r->bRequest] == NULL)
			return -1;
		return ep0stdhandler[r->bRequest](r);
	case RTVENDOR:
		if(r->bRequest >= nelem(ep0vhandler) ||
		ep0vhandler[r->bRequest] == NULL)
			return -1;
		return ep0vhandler[r->bRequest](r);
	default:
		return -1;
	}
}

static void
fifoput(int ep, void *dv, int len)
{
	volatile void *r;
	uint8_t *d;

	r = &USBFIFO0 + ep;
	d = dv;
	while(len >= 4){
		*(uint32_t*)r = *(uint32_t*)d;
		d += 4;
		len -= 4;
	}
	if(len >= 2){
		*(uint16_t*)r = *(uint16_t*)d;
		d += 2;
		len -= 2;
	}
	if(len == 1)
		*(uint8_t*)r = *d;

}

static enum {
	EP0RESET,
	EP0SETUP,
	EP0TXDATA,
	EP0TXDATAL,
	EP0TXSTATUS,
	EP0RXDATA,
	EP0ZLEN,
} ep0state;

static void
ep0txkick(USBReq *r)
{
	int n;

	assert(r->ptr >= 0 && r->ptr <= r->len);
	if(USBE0CSR0bits.TXRDY){
		printf("USB: tried to write to full FIFO\n");
		return;
	}
	n = r->len - r->ptr;
	if(n > MAXPKT) n = MAXPKT;
	//dprintf("USB: TX: sending %d\n", n);
	fifoput(0, r->data + r->ptr, n);
	r->ptr += n;
	if(n == MAXPKT && r->ptr < r->wLength){
		ep0state = EP0TXDATA;
		USBE0CSR0bits.TXRDY = 1;
	}else{
		ep0state = EP0TXDATAL;
		USBE0CSR0 |= _USBE0CSR0_TXRDY_MASK | _USBE0CSR0_DATAEND_MASK;
	}

}

static void
usbep0(void)
{
	int nb, i, rc;
	static uint8_t d[MAXPKT];
	uint32_t v;
	static USBReq r;

	if(ep0state == EP0RESET){
		ep0state = EP0SETUP;
		poststatus = NULL;
	}
	if(USBE0CSR0bits.SETEND){
		USBE0CSR0bits.SETENDC = 1;
		printf("USB: setup ended prematurely\n");
		if(ep0state != EP0ZLEN)
			ep0state = EP0SETUP;
	}
	if(USBE0CSR0bits.STALLED){
		USBE0CSR0bits.STALLED = 0;
		return;
	}
	switch(ep0state){
	case EP0TXDATA:
		ep0txkick(&r);
		return;
	case EP0TXDATAL:
		dprintf("USB: TX: status done\n");
		if(0){
	case EP0TXSTATUS:
	case EP0ZLEN:
			dprintf("USB: sent status word\n");
		}
		if(poststatus != NULL){
			poststatus();
			poststatus = NULL;
		}
		ep0state = EP0SETUP;
		return;
	}
	if(!USBE0CSR0bits.RXRDY) return;
	nb = USBE0CSR2bits.RXCNT;
	if(nb > MAXPKT){
		printf("USB: received oversized packet, %d > %d", nb, MAXPKT);
		ep0stall();
		ep0state = EP0SETUP;
		return;
	}
	for(i = 0; i < nb; i += 4){
		v = USBFIFO0;
		if(i < MAXPKT)
			*(uint32_t*)(d + i) = v;
	}
	switch(ep0state){
	case EP0SETUP:
		if(nb != 8){
			printf("USB: setup packet has the wrong size, %d != 8\n",
			nb);
			USBE0CSR0bits.FLUSH = 1;
			return;
		}
		mkusbreq(&r, d);

		if(r.wLength == 0){
			if(ep0req(&r) >= 0){
				USBE0CSR0 |= _USBE0CSR0_RXRDYC_MASK |
				_USBE0CSR0_DATAEND_MASK;
				ep0state = EP0ZLEN;
			}else
				ep0stall();
		}else if((r.bmRequestType & RTTOHOST) == 0){
			USBE0CSR0bits.RXRDYC = 1;
			ep0state = EP0RXDATA;
		}else{
			rc = ep0req(&r);
			if(rc >= 0){
				r.len = rc;
				USBE0CSR0bits.RXRDYC = 1;
				ep0txkick(&r);
			}else
				ep0stall();
		}
		break;
	case EP0RXDATA:
		//dprintf("USB: RX: got %d bytes\n", nb);
		if(r.ptr + nb > r.wLength){
			printf("USB: received too much data during control
			transfer\n");
			ep0stall();
			ep0state = EP0SETUP;
		}
		memcpy(r.data + r.ptr, d, nb);
		r.ptr += nb;
		if(nb < MAXPKT || r.ptr == r.wLength){
			r.len = r.wLength;
			r.wLength = r.ptr;
			if(ep0req(&r) >= 0){
				USBE0CSR0bits.RXRDYC = 1;
				USBE0CSR0bits.DATAEND = 1;
				ep0state = EP0TXSTATUS;
			}else{
				ep0stall();
				ep0state = EP0SETUP;
			}
		}else
			USBE0CSR0bits.RXRDYC = 1;
		break;
	default:
		printf("RX in state %d\n", ep0state);
		ep0stall();
		ep0state = EP0SETUP;
	}
}

static void
qpop(USBQueue *q)
{
	int s;
	USBPkt *p;

	s = splhi();
	p = q->first;
	if(p == NULL) goto out;
	q->first = p->next;
	if(q->nextp == &p->next)
		q->nextp = &q->first;
	q->qalloc -= p->len + sizeof(USBPkt);
	free(p);
out: splx(s);
}

static void
txkick(USBQueue *q)
{
	int s;
	int n;
	volatile void *fifo;
	USBPkt *p;
	USBEp *ep;

	if(q == NULL) return;
	s = splhi();
	ep = q->ep;
	if(ep == NULL || usbstate != USBCONFIG || ((&USBE0CSR0)[4*ep->devep] &
	_USBE1CSR0_TXPKTRDY_MASK) != 0 || q->first == NULL) goto out;
	fifo = &USBFIFO0 + ep->devep;
	p = q->first;
	for(n = 0; n < ep->fifosz; n++){
		if(p->ptr >= p->len){
			qpop(q);
			if(p = q->first, p == NULL) break;
		}
		*(uint8_t*)fifo = p->data[p->ptr++];
	}
	if(n != 0)
		(&USBE0CSR0)[4*ep->devep] |= _USBE1CSR0_TXPKTRDY_MASK;
out:
	splx(s);
}

static void
kickall(void)
{
	int i;

	for(i = 1; i < 8; i++)
		txkick(eptx[i].q);
}

static void
usbepntxirq(USBEp *ep)
{
	txkick(ep->q);
}

static void
usbepnrxirq(USBEp *ep)
{
	dprintf("EP%d RX interrupt\n", ep->devep);
	if(ep->targep == 0) return;
}

void __ISR(_USB_VECTOR, USBIPL)
usbirq(void)
{
	uint32_t csr0, csr1, csr2;
	int i;

	csr0 = USBCSR0;
	csr1 = USBCSR1;
	csr2 = USBCSR2;
	IFS4CLR = _IFS4_USBIF_MASK;
	if((csr0 & _USBCSR0_EP0IF_MASK) != 0)
		usbep0();
	if((csr0 & 0xfe0000) != 0)
		for(i = 1; i < 8; i++)
			if((csr0 & 1<<16+i) != 0)
				usbepntxirq(&eptx[i]);
	if((csr1 & 0xfe) != 0)
		for(i = 1; i < 8; i++)
			if((csr1 & 1<<16+i) != 0)
				usbepnrxirq(&eprx[i]);
	if((csr2 & _USBCSR2_RESETIF_MASK) != 0)
		usbreset();
}

void
usbinit(void)
{
	bulkep(1, 0x81, 0, &msgq);
	bulkep(2, 0x82, 0, &corrq);

	USBCRCONbits.USBIDOVEN = 1;
	USBCRCONbits.USBIDVAL = 1;
	USBCRCONbits.USBIE = 1;

	USBCSR0bits.HSEN = 1;
	USBCSR2bits.RESETIE = 1;

	IPC33bits.USBIP = USBIRQPRI;
	IPC33bits.USBIS = USBIRQSUB;
	IPC33bits.USBDMAIP = USBDMAIRQPRI;
	IPC33bits.USBDMAIS = USBDMAIRQSUB;
	IEC4bits.USBIE = 1;
	IEC4bits.USBDMAIE = 1;

	USBCSR0bits.SOFTCONN = 1;
}

int
qwrite(USBQueue *q, const void *data, int len)
{
	int n, s;
	USBPkt *p;
	int over;

	s = splhi();
	n = sizeof(USBPkt) + len;
	assert(n <= q->maxq);
	q->qalloc += n;
	over = 0;
	while(q->qalloc >= q->maxq){
		qpop(q);
		over++;
	}
	p = malloc(n);
	assert(p != NULL);
	p->len = len;
	p->ptr = 0;
	p->next = NULL;
	memcpy(p->data, data, len);
	if(q->nextp == NULL)
		q->first = p;
	else
		*q->nextp = p;
	q->nextp = &p->next;
	txkick(q);
	splx(s);
	return over;
}


Sat Jun 15 10:59:27 EDT 2019
defend forward

Fri Jun 14 23:47:52 EDT 2019
this cdc book sucks

Fri Jun 14 19:46:56 EDT 2019
fuck this

Fri Jun 14 14:25:48 EDT 2019
https://imgur.com/a/nwMon8k

Fri Jun 14 14:18:13 EDT 2019
https://i.imgur.com/OX4Ae7U.png

Fri Jun 14 13:52:33 EDT 2019
июн 15 03:48:17 pc nohang[852]: # 1786 1743 0 0 0 0 S 21 2 0 sudo
июн 15 03:48:17 pc nohang[852]: # 1787 1786 0 0 0 0 D 53 2 1 journalctl
июн 15 03:48:17 pc nohang[852]: # 1788 1759 929 929 0 1000 D 11013 9362 1634 tail
июн 15 03:48:17 pc nohang[852]:
###################################################################################################################
июн 15 03:48:17 pc nohang[852]: Found 86 processes with existing /proc/[pid]/exe
июн 15 03:48:17 pc nohang[852]: Process with highest badness (found in 6000 ms):
июн 15 03:48:17 pc nohang[852]: PID: 1788, Name: tail, badness: 929


prev | next