Esempio n. 1
0
File: hd.c Progetto: wwssllabcd/myOS
/**
 * <Ring 1> This routine handles DEV_READ and DEV_WRITE message.
 *
 * @param p Message ptr.
 *****************************************************************************/
PRIVATE void hd_rdwt(MESSAGE * p)
{
    // p->DEVICE 為 0x20,也就是 hd2a
    int pDev = p->DEVICE;
    int drive = DRV_OF_DEV(p->DEVICE);
    u64 pos = p->POSITION;
    assert((pos >> SECTOR_SIZE_SHIFT) < (1 << 31));

    /**
     * We only allow to R/W from a SECTOR boundary:
     */
    assert((pos & 0x1FF) == 0);

    u32 sect_nr = (u32)(pos >> SECTOR_SIZE_SHIFT); /* pos / SECTOR_SIZE */

    //取出logic index
    int logidx = (p->DEVICE - MINOR_hd1a) % NR_SUB_PER_DRIVE;

    // 找出某個partition的LBA,
    // MAX_PRIM=9,代表Hd0~Hd9為primary的編號,超過9以上的編號都是logic
    sect_nr += p->DEVICE < MAX_PRIM ?
               hd_info[drive].primary[p->DEVICE].base :
               hd_info[drive].logical[logidx].base;

    ERIC_HD("\nHDRW=%x", sect_nr);

    struct hd_cmd cmd;
    cmd.features	= 0;
    cmd.count	= (p->CNT + SECTOR_SIZE - 1) / SECTOR_SIZE;
    cmd.lba_low	= sect_nr & 0xFF;
    cmd.lba_mid	= (sect_nr >>  8) & 0xFF;
    cmd.lba_high= (sect_nr >> 16) & 0xFF;
    cmd.device	= MAKE_DEVICE_REG(1, drive, (sect_nr >> 24) & 0xF);
    cmd.command	= (p->type == DEV_READ) ? ATA_READ : ATA_WRITE;

    hd_cmd_out(&cmd);

    int bytes_left = p->CNT;
    void * la = (void*)va2la(p->PROC_NR, p->BUF);

    while (bytes_left) {
        //一次只讀512 byte
        int bytes = min(SECTOR_SIZE, bytes_left);

        if (p->type == DEV_READ) {
            interrupt_wait();
            port_read(REG_DATA, hdbuf, SECTOR_SIZE);
            phys_copy(la, (void*)va2la(TASK_HD, hdbuf), bytes);
        }
        else {
            if (!waitfor(STATUS_DRQ, STATUS_DRQ, HD_TIMEOUT))
                panic("hd writing error.");

            port_write(REG_DATA, la, bytes);
            interrupt_wait();
        }
        bytes_left -= SECTOR_SIZE;
        la += SECTOR_SIZE;
    }
}
Esempio n. 2
0
File: hd.c Progetto: cosail/lwos
/*
 * <ring 1> this routine handles DEV_READ and DEV_WRITE message.
 *
 * @param msg - message
 */
static void hd_rdwt(MESSAGE *msg)
{
	int drive = DRV_OF_DEV(msg->DEVICE);

	u64 pos = msg->POSITION;
	assert((pos >> SECTOR_SIZE_SHIFT) < (1 << 31));

	assert((pos & 0x1ff) == 0);

	u32 sect_nr = (u32)(pos >> SECTOR_SIZE_SHIFT);
	int logidx = (msg->DEVICE - MINOR_hd1a) % NR_SUB_PER_DRIVE;
	sect_nr += msg->DEVICE < MAX_PRIM ?
		hd_info[drive].primary[msg->DEVICE].base :
		hd_info[drive].logical[logidx].base;

	struct hd_cmd cmd;
	cmd.features = 0;
	cmd.count = (msg->CNT + SECTOR_SIZE - 1) / SECTOR_SIZE;
	cmd.lba_low = sect_nr & 0xff;
	cmd.lba_mid = (sect_nr >> 8) & 0xff;
	cmd.lba_high = (sect_nr >> 16) & 0xff;
	cmd.device = MAKE_DEVICE_REG(1, drive, (sect_nr >> 24) & 0xf);
	cmd.command = (msg->type == DEV_READ) ? ATA_READ : ATA_WRITE;

	hd_cmd_out(&cmd);

	int bytes_left = msg->CNT;
	void *la = (void*)va2la(msg->PROC_NR, msg->BUF);

	while (bytes_left > 0)
	{
		int bytes = min(SECTOR_SIZE, bytes_left);
		if (msg->type == DEV_READ)
		{
			interrupt_wait();
			port_read(REG_DATA, hdbuf, SECTOR_SIZE);
			phys_copy(la, (void*)va2la(TASK_HD, hdbuf), bytes);
		}
		else
		{
			if (!waitfor(STATUS_DRQ, STATUS_DRQ, HD_TIMEOUT))
			{
				panic("hd writing error.");
			}

			port_write(REG_DATA, la, bytes);
			interrupt_wait();
		}

		bytes_left -= SECTOR_SIZE;
		la += SECTOR_SIZE;
	}
}
Esempio n. 3
0
/*
1.函数内部需要注意:while(1),while(-1)都会执行循环体,只有while(0)时才跳出循环体
2.目前只能处理读写数据长度为SECTOR_SIZE整数倍的请求,否则会出错
*/
static void hd_rdwt(MESSAGE *message){
    int hd_index=HD_INDEX(message->device);
    int hd_part_index=HD_PART_INDEX(message->device);

    u64 position=message->position;
#ifdef DEBUG_HD
    printl("position=%d\n",position);
#endif
    assert((position>>SECTOR_SIZE_SHIFT)<(1<<31),"");
    assert(position%SECTOR_SIZE==0,"hd readwrite start position must be the multiple of SECTOR_SIZE");//读取的起始位置必须在扇区的起始位置

    HD_COMMAND hd_command;
    u32 base=get_part_info(&hd_info[hd_index],hd_part_index)->base;
    u32 sector_index=base+(u32)(position>>SECTOR_SIZE_SHIFT);
    int sector_length=(message->length+SECTOR_SIZE-1)/SECTOR_SIZE;
    int cmd=(message->type==INFO_FS_READ)?ATA_READ:ATA_WRITE;
    set_command(&hd_command,hd_index,0,0,sector_length,sector_index,cmd);
    hd_command_out(&hd_command);

    int bytes_left=message->length;
#ifdef DEBUG_HD
    printl("sector_index=%d sector_length=%d bytes_left=%d\n",sector_index,sector_length,bytes_left);
#endif
    void *la=(void *)va2la(message->source_pid,message->arg_pointer);
#ifdef DEBUG_HD
    printl("source_pid=%d la[0]=%d\n",message->source_pid,*(int*)la);
#endif
//此处需要注意:while(1),while(-1)都会执行循环体,只有while(0)时才跳出循环体
    while(bytes_left>0){
        int bytes=min(SECTOR_SIZE,bytes_left);
        if(message->type==INFO_FS_READ){
            interrupt_wait();
            port_read(REG_P_DATA,hdbuf,SECTOR_SIZE);
            memcpy(la,(void *)va2la(TASK_HD,hdbuf),bytes);
        }else{
            if(!wait_for(STATUS_DRQ_MASK,STATUS_DRQ,HD_TIME_OUT))
                panic("hd writing error!\n");
            /* printl("bytes=%d",bytes); */
            port_write(REG_P_DATA,la,bytes);
            /* printl("test1"); */
            interrupt_wait();
            /* printl("test2"); */
        }
        bytes_left-=bytes;
        la+=bytes;
        /* printl("(bytes_left>0)=%d\n",bytes_left>0); */
    }
#ifdef DEBUG_HD
    printl("hd_rdwt ok!\n");
#endif
}
Esempio n. 4
0
/*
功能:
    获取硬盘信息。主要是获取对应硬盘的容量,获取的信息保存在hd_info中
参数:
    device:系统统一设备编号
返回值:
    (无)
*/
static void hd_identify(int index){
    int hd_index=HD_INDEX(index);

    struct s_hd_command cmd;
    cmd.device=MAKE_DEVICE_REG(0,hd_index,0);
    cmd.command=ATA_IDENTIFY;
    hd_command_out(&cmd);

#ifdef DEBUG_HD
    printl("interrupt_wait\n");
#endif

    interrupt_wait();

    port_read(REG_P_DATA,hdbuf,SECTOR_SIZE);

#ifdef DEBUG_HD
    print_identify_info((u16*)hdbuf); 
#endif
    
    u16 *hdinfo=(u16*)hdbuf;
    //硬盘基址 
    hd_info[hd_index].primary[0].base=0;
    //硬盘扇区数
    hd_info[hd_index].primary[0].size=((int)hdinfo[61]<<16)+hdinfo[60];
}
Esempio n. 5
0
PRIVAATE void hd_rdwt(MESSAGE *p)
{
    int drive = DRV_OF_DEV(p->DEVICE);
    
    u64_t pos = p->POSITION;
    
    u32_t sect_nr = (u32_t)(pos >> SECTOR_SIZE_SHIFT);

    int logidx = (p->DEVICE - MINOR_HD1a) % NR_SUB_PER_DRIVE;
    sect_nr += p->DEVICE < MAX_PRIM ?
        hd_info[drive].primary[p->DEVICE].base :
        hd_info[drive].logical[logidx].base;

    struct hd_cmd cmd;
    cmd.features = 0;
    cmd.count = (p->CNT + SECTOR_SIZE - 1) / SECTOR_SIZE;
    cmd.lba_low = sect_nr & 0xff;
    cmd.lba_mid = (sect_nr >> 8) & 0xff;
    cmd.lba_high = (sect_nr >> 16) & 0xff;
    cmd.device = MAKE_DEVICE_REG(1, drive, (sect_nr >> 24) & 0xf);
    cmd.command = (p->type == DEV_READ) ? ATA_READ : ATA_WRITE;
    hd_cmd_out(&cmd);

    int bytes_left = p->CNT;
    void *la = (void*)va2la(p->PROC_NR, p->BUF);

    while (bytes_left) {
        int bytes = min(SECTOR_SIZE, bytes_left);
        if (p->type == DEV_READ) {
            interrupt_wait();
            port_read(REG_DATA, hdbuf, SECTOR_SIZE);
            phys_copy(la, (void*)va2la(TASK_HD, hdbuf), bytes);
        } else {
            if (!waitfor(STATUS_DRQ, STATUS_DRQ, HD_TIMEOUT)) {
                kprintf("[KERNEL ERROR]hd writing error.\n");
                break;
            }
            port_write(REG_DATA, la, bytes);
            interrupt_wait();
        }
        bytes_left -= SECTOR_SIZE;
        la += SECTOR_SIZE;
    }
}
Esempio n. 6
0
/**
 * <Ring 1> Get the disk information.
 * 
 * @param drive  Drive Nr.
 *****************************************************************************/
PRIVATE void hd_identify(int drive)
{
	struct hd_cmd cmd;
	cmd.device  = MAKE_DEVICE_REG(0, drive, 0);
	cmd.command = ATA_IDENTIFY;
	hd_cmd_out(&cmd);
	interrupt_wait();
	port_read(REG_DATA, hdbuf, SECTOR_SIZE);

	print_identify_info((u16*)hdbuf);
}
Esempio n. 7
0
File: hd.c Progetto: Zach41/OS
PRIVATE void hd_rdwt(MESSAGE* p_msg) {
    int drive = DRV_OF_DEV(p_msg -> DEVICE);
    u64 pos = p_msg -> POSITION;

    assert((pos & 0x1FF) == 0);	/* 只允许从扇区边界开始读 */

    u32 sect_nr = (u32)(pos >> SECTOR_SIZE_SHIFT);
    int logidx  = (p_msg -> DEVICE - MINOR_hd1a) % NR_SUB_PER_DRIVE;
    sect_nr    += p_msg -> DEVICE < MAX_PRIM ? hd_info[drive].primary[p_msg -> DEVICE].base : hd_info[drive].logical[logidx].base;
    
    HD_CMD cmd;
    cmd.features = 0;
    cmd.count    = (p_msg -> CNT + SECTOR_SIZE - 1) / SECTOR_SIZE;
    cmd.lba_low  = sect_nr & 0xFF;
    cmd.lba_mid  = (sect_nr >> 8) & 0xFF;
    cmd.lba_high = (sect_nr >> 16) & 0xFF;
    cmd.device   = MAKE_DEVICE_REG(1, drive, (sect_nr >> 24) & 0xF);
    cmd.command  = (p_msg -> type == DEV_READ) ? ATA_READ : ATA_WRITE;
    hd_cmd_out(&cmd);

    int bytes_left = p_msg -> CNT;
    void* la = (void*)va2la(p_msg -> PROC_NR, p_msg -> BUF);

    while (bytes_left > 0) {
	int bytes = min(bytes_left, SECTOR_SIZE);
	if (p_msg -> type == DEV_READ) {
	    /* 一次中断一个扇区 */
	    interrupt_wait();
	    port_read(REG_DATA, hdbuf, SECTOR_SIZE);
	    memcpy(la, (void*)va2la(TASK_HD, hdbuf), bytes);
	} else {
	    if (!waitfor(STATUS_DRQ, STATUS_DRQ, HD_TIMEOUT))
		panic("HD writing error");
	    port_write(REG_DATA, la, bytes);
	    interrupt_wait();
	}
	la += bytes;
	bytes_left -= bytes;
    }
}
Esempio n. 8
0
File: hd.c Progetto: cosail/lwos
/*
 *	<ring 1> get the disk information
 */
static void hd_identify(int drive)
{
	struct hd_cmd cmd;
	cmd.device = MAKE_DEVICE_REG(0, drive, 0);
	cmd.command = ATA_INDENTIFY;
	hd_cmd_out(&cmd);
	interrupt_wait();
	port_read(REG_DATA, hdbuf, SECTOR_SIZE);

	print_identify_info((u16*)hdbuf);
	
	u16 * hdinfo = (u16*)hdbuf;
	hd_info[drive].primary[0].base = 0;
	hd_info[drive].primary[0].size = ((int)hdinfo[61] << 16) + hdinfo[60];
}
Esempio n. 9
0
int netif_event_wait(spdid_t spdid, struct cos_array *d)
{
	int ret_sz = 0;

	/* if (!cos_argreg_arr_intern(d)) return -EINVAL; */
	/* if (d->sz < MTU) return -EINVAL; */

	interrupt_wait();
	NET_LOCK_TAKE();
	if (interrupt_process(d->mem, d->sz, &ret_sz)) BUG();
	NET_LOCK_RELEASE();
	d->sz = ret_sz;

	return 0;
}
Esempio n. 10
0
PRIVATE void get_part_table(int drive, int sectnr, struct part_ent *entry)
{
    struct hd_cmd cmd;
    cmd.features = 0;
    cmd.count = 1;
    cmd.lba_low = sect_nr & 0xff;
    cmd.lba_mid = (sect_nr >> 8) & 0xff;
    cmd.lba_high = (sect_nr >> 16) & 0xff;
    cmd.device = MAKE_DEVICE_REG(1, drive, (sect_nr >> 24) & 0xf);
    cmd.command = ATA_READ;
    hd_cmd_out(&cmd);
    interrupt_wait();

    port_read(REG_DATA, hdbuf, SECTOR_SIZE);
    memcpy(entry, hdbuf + PARTITION_TABLE_OFFSET, sizeof (struct part_ent) * NR_PART_PER_DRIVE);
}
Esempio n. 11
0
void serialin(USART_TypeDef* uart, unsigned int intr)
{
	int fd;
	char c;
	mkfifo("/dev/tty0/in", 0);
	fd = open("/dev/tty0/in", 0);

    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

	while (1) {
		interrupt_wait(intr);
		if (USART_GetFlagStatus(uart, USART_FLAG_RXNE) == SET) {
			c = USART_ReceiveData(uart);
			write(fd, &c, 1);
		}
	}
}
Esempio n. 12
0
void serialin(volatile unsigned int* uart, unsigned int intr) {
	int fd;
	char c;
	mkfifo("/dev/tty0/in", 0);
	fd = open("/dev/tty0/in", 0);

	/* enable RX interrupt on UART */
	*(uart + UARTIMSC) |= UARTIMSC_RXIM;

	while(1) {
		interrupt_wait(intr);
		*(uart + UARTICR) = UARTICR_RXIC;
		if(!(*(uart + UARTFR) & UARTFR_RXFE)) {
			c = *uart;
			write(fd, &c, 1);
		}
	}
}
Esempio n. 13
0
/*
功能:
    获得一个分区内的完整分区表,即包含四项分区表信息    
参数:
    entry:
返回值:
    (无)
*/
static void get_part_table(int index,int sector_index,struct s_hd_part_entry *entry,int entry_count){
    int hd_index=HD_INDEX(DEVICE(index));
    struct s_hd_command cmd;

    set_command(&cmd,hd_index,0,0,1,sector_index,ATA_READ);

#ifdef DEBUG
    printl("feathures=%d   count=%d   lba_low=%d lba_mid=%d lba_high=%d device=%d command=%d\n",cmd.features,cmd.count,cmd.lba_low,cmd.lba_mid,cmd.lba_high,cmd.device,cmd.command);
#endif

    hd_command_out(&cmd);//命令发出
    interrupt_wait();//等待硬盘中断

    port_read(REG_P_DATA,hdbuf,SECTOR_SIZE);

    memcpy(entry,
           hdbuf+PARTITION_TABLE_OFFSET,
           sizeof(struct s_hd_part_entry)*entry_count);
}
Esempio n. 14
0
File: hd.c Progetto: Zach41/OS
PRIVATE void hd_identify(int drive) {
    HD_CMD cmd;

    cmd.device  = MAKE_DEVICE_REG(0, drive, 0);
    cmd.command = ATA_IDENTIFY;	/* 向硬盘发送IDENTIFY指令 */

    hd_cmd_out(&cmd);
    interrupt_wait();

    /* 中断结束 */
    port_read(REG_DATA, hdbuf, SECTOR_SIZE);

    /* print_identify_info((u16*)hdbuf); */

    u16* hdinfo = (u16*)hdbuf;

    hd_info[drive].primary[0].base = 0;
    hd_info[drive].primary[0].size = ((int)hdinfo[61] << 16) + hdinfo[60];
}
Esempio n. 15
0
File: hd.c Progetto: wwssllabcd/myOS
/**
 * <Ring 1> Get the disk information.
 *
 * @param drive  Drive Nr.
 *****************************************************************************/
PRIVATE void hd_identify(int drive)
{
    struct hd_cmd cmd;
    cmd.device  = MAKE_DEVICE_REG(0, drive, 0);
    cmd.command = ATA_IDENTIFY;
    ERIC_DEBUG(",IdTB");
    hd_cmd_out(&cmd);
    interrupt_wait();

    ERIC_DEBUG(",ReadData");
    port_read(REG_DATA, hdbuf, SECTOR_SIZE);
    print_identify_info((u16*)hdbuf);

    u16* hdinfo = (u16*)hdbuf;

    hd_info[drive].primary[0].base = 0;
    /* Total Nr of User Addressable Sectors */
    hd_info[drive].primary[0].size = ((int)hdinfo[61] << 16) + hdinfo[60];
}
Esempio n. 16
0
void serialout(USART_TypeDef* uart, unsigned int intr)
{
	int fd;
	char c;
	mkfifo("/dev/tty0/out", 0);
	fd = open("/dev/tty0/out", 0);

	while (1) {
		read(fd, &c, 1);
    	
		USART_ITConfig(USART2, USART_IT_TXE, ENABLE);
		while (USART_GetFlagStatus(uart, USART_FLAG_TXE) != SET) {
    		interrupt_wait(intr);
    	}
		USART_ITConfig(USART2, USART_IT_TXE, DISABLE);
    	
    	USART_SendData(USART2, c);
	}
}
Esempio n. 17
0
File: hd.c Progetto: Zach41/OS
PRIVATE void get_part_table(int drive, int sect_nr, PART_ENT* entry) {
    HD_CMD cmd;
    /* 设置命令 */
    cmd.features = 0;
    cmd.count    = 1;
    cmd.lba_low  = sect_nr & 0xFF;
    cmd.lba_mid  = (sect_nr >> 8) & 0xFF;
    cmd.lba_high = (sect_nr >> 16) & 0xFF;
    cmd.device   = MAKE_DEVICE_REG(1, drive, (sect_nr >> 24) & 0xF); /* LBA Mode */

    cmd.command  = ATA_READ;

    hd_cmd_out(&cmd);
    /* 等待中断发生 */
    interrupt_wait();
    /* 数据已经就绪 */
    port_read(REG_DATA, hdbuf, SECTOR_SIZE);
    /* 分区表的偏移为PARTITION_TABLE_OFFSET = 0x1BE */
    memcpy(entry, hdbuf + PARTITION_TABLE_OFFSET, sizeof(PART_ENT) * NR_PART_PER_DRIVE);
}
Esempio n. 18
0
void serialout(volatile unsigned int* uart, unsigned int intr) {
	int fd;
	char c;
	int doread = 1;
	mkfifo("/dev/tty0/out", 0);
	fd = open("/dev/tty0/out", 0);

	/* enable TX interrupt on UART */
	*(uart + UARTIMSC) |= UARTIMSC_TXIM;

	while(1) {
		if(doread) read(fd, &c, 1);
		doread = 0;
		if(!(*(uart + UARTFR) & UARTFR_TXFF)) {
			*uart = c;
			doread = 1;
		}
		interrupt_wait(intr);
		*(uart + UARTICR) = UARTICR_TXIC;
	}
}
Esempio n. 19
0
void serialout(USART_TypeDef* uart, unsigned int intr)
{
    int fd;
    char c;
    int doread = 1;
    mkfifo("/dev/tty0/out", 0);
    fd = open("/dev/tty0/out", 0);

    while (1) {
        if (doread)
            read(fd, &c, 1);
        doread = 0;
        if (USART_GetFlagStatus(uart, USART_FLAG_TXE) == SET) {
            USART_SendData(uart, c);
            USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
            doread = 1;
        }
        interrupt_wait(intr);
        USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
    }
}
Esempio n. 20
0
void serialin(void* arg)
{
	int fd;
	char c;
	mkfifo("/dev/tty0/in", 0);
	fd = open("/dev/tty0/in", 0);

    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

	while (1) {
//		interrupt_wait(intr);
		interrupt_wait(USART2_IRQn);
		
/*		if (USART_GetFlagStatus(uart, USART_FLAG_RXNE) == SET) {
			c = USART_ReceiveData(uart);
*/	
		if (USART_GetFlagStatus((USART_TypeDef *)USART2, USART_FLAG_RXNE) == SET) {
			c = USART_ReceiveData((USART_TypeDef *)USART2);
			write(fd, &c, 1);
		}
	}
}
Esempio n. 21
0
File: hd.c Progetto: wwssllabcd/myOS
/**
 * <Ring 1> Get a partition table of a drive.
 *
 * @param drive   Drive nr (0 for the 1st disk, 1 for the 2nd, ...)n
 * @param sect_nr The sector at which the partition table is located.
 * @param entry   Ptr to part_ent struct.
 *****************************************************************************/
PRIVATE void get_part_table(int drive, int sect_nr, struct part_ent * entry)
{
    ERIC_HD("\nGetPTable=%x", sect_nr);

    struct hd_cmd cmd;
    // ata read cmd ( 0x20 )
    cmd.features	= 0;
    cmd.count	= 1;
    cmd.lba_low	= sect_nr & 0xFF;
    cmd.lba_mid	= (sect_nr >>  8) & 0xFF;
    cmd.lba_high	= (sect_nr >> 16) & 0xFF;
    cmd.device	= MAKE_DEVICE_REG(1, /* LBA mode*/
                                  drive,
                                  (sect_nr >> 24) & 0xF);
    cmd.command	= ATA_READ;
    hd_cmd_out(&cmd);
    interrupt_wait();

    port_read(REG_DATA, hdbuf, SECTOR_SIZE);
    memcpy(entry,
           hdbuf + PARTITION_TABLE_OFFSET,
           sizeof(struct part_ent) * NR_PART_PER_DRIVE);
}
Esempio n. 22
0
File: netif.c Progetto: songjiguo/C3
int netif_event_wait(spdid_t spdid, char *mem, int sz)
{
	int ret_sz = 0;

	if (sz < MTU) return -EINVAL;

	/* printc("before %d: I\n", cos_get_thd_id()); */
	/* rdtscll(start); */
	interrupt_wait();
	/* rdtscll(end); */
	/* pnums++; */
	/* avg += end-start; */
	/* if (pnums%100000 == 0) { */
	/* 	printc("pnums %llu avg %llu\n", pnums, avg); */
	/* } */
	/* printc("after %d: I\n", cos_get_thd_id()); */
	NET_LOCK_TAKE();
	if (interrupt_process(mem, sz, &ret_sz)) BUG();
	interrupt_process_cnt++;
	NET_LOCK_RELEASE();

	return ret_sz;
}
Esempio n. 23
0
void * fpga_server(void * arg) {
    int rc;
    gpio_out_uni * temp_state = NULL; //If this variable is set, the server will deassert the output latch

    prctl(PR_SET_NAME, FPGA_SERVER, 0, 0, 0);

    record("-->FPGA Server thread started....\n");

    /*initialize semaphore*/
    sem_init(&dma_control_sem, 0, 0); //initialize semaphore to zero

    /*open fpga device*/
    open_fpga();

    /*Allocate buffer for image fragments*/
    uint i;
    for (i = 0; i < NUM_FRAGMENT; i++) {
        allocate_buffer(&dma_params[i], &pci_buffer[i], &virt_buf[i]);
    }

    /*initialize GPIO pins*/
    rc = init_gpio();
    if (rc == FALSE) {
        record("Error initializing GPIO pins\n");
    }

    /*initialize DMA pipeline*/
    initializeDMA();

    /*FPGA server main control loop*/
    while (ts_alive) {
        U32 interrupt = 0;

        /*wait on interrupt for DMA and GPIO input*/
        rc = interrupt_wait(&interrupt);
        if (rc == FALSE) {
            record(RED "Error during wait\n" NO_COLOR);
        }

        /**
         * Unlatch the power latch if it was latched before timeout
         * 
         * This statement requires that the timeout on the interrupt wait must be 
         * similar to the latch pulse length (66ms).
         */
        if (temp_state) {

            /*deassert latch*/
            temp_state->bf.latch = 0;

            /*Poke unlatched value to FPGA*/
            rc = poke_gpio(OUTPUT_GPIO_ADDR, temp_state->val);
            if (rc == FALSE) {
                record(RED "Error writing GPIO output\n" NO_COLOR);
            }

            /*free gpio value*/
            free(temp_state); //Free GPIO output struct from assert
            temp_state = NULL;
        }

        /*take action based off what type of interrupt*/
        if (interrupt == INP_INT) {

            /*Call function to handle input interrupt from FPGA*/
            record("Interrupt received\n");

            rc = handle_fpga_input();
            if (rc == FALSE) {
                record(RED "Error handling FPGA input\n" NO_COLOR);
            } else if (rc == DMA_AVAILABLE) { // DMA available in buffer, begin transfer

                /*Wake up science timeline waiting for readout completion*/
                sem_post(&dma_control_sem);

                record("Perform DMA transfer from FPGA\n");

                for (i = 0; i < NUM_FRAGMENT; i++) {
                    dmaRead(dma_params[i], DMA_TIMEOUT);
                }

                // Return to IDLE state
                record("DMA Complete, Returning to IDLE state\n");
                output_ddr2_ctrl &= 0x00FFFFFF;
                output_ddr2_ctrl |= (0x02 << 24);
                WriteDword(&fpga_dev, 2, OUTPUT_DDR2_CTRL_ADDR, output_ddr2_ctrl);
                output_ddr2_ctrl &= 0x00FFFFFF;
                output_ddr2_ctrl |= (0x00000000 << 24);
                WriteDword(&fpga_dev, 2, OUTPUT_DDR2_CTRL_ADDR, output_ddr2_ctrl);
                ;

                record("Sort image\n");
                filter_sort(dma_image);

                record("Enqueue image to writer\n");
                enqueue(&lqueue[fpga_image], dma_image);

            }


        } else if (interrupt == TIMEOUT_INT) {

            /*check if new GPIO output is available*/
            if (occupied(&lqueue[gpio_out])) {
                gpio_out_uni * gpio_out_val = dequeue(&lqueue[gpio_out]);

                if (gpio_out_val != NULL) {
                    /*Check if request or assert*/
                    if (gpio_out_val->val == REQ_POWER) {

                        /*request pin values*/
                        rc = peek_gpio(OUTPUT_GPIO_ADDR, &(gpio_out_val->val));
                        if (rc == FALSE) {
                            record(RED "Error reading GPIO request\n" NO_COLOR);
                        }

                        enqueue(&lqueue[gpio_req], gpio_out_val);
                    } else {
                        /*apply output if not request*/
                        rc = poke_gpio(OUTPUT_GPIO_ADDR, gpio_out_val->val);
                        if (rc == FALSE) {
                            record(RED "Error writing GPIO output\n" NO_COLOR);
                        }

                        usleep(1000); //sleep for 1ms before applying latch

                        /*apply latch*/
                        gpio_out_val->bf.latch = 1;

                        /*apply latched output*/
                        rc = poke_gpio(OUTPUT_GPIO_ADDR, gpio_out_val->val);
                        if (rc == FALSE) {
                            record(RED "Error writing GPIO output\n" NO_COLOR);
                        }

                        temp_state = gpio_out_val; //write to this variable so we know to delatch next timeout
                    }
                } else {
                    record("Received NULL GPIO output struct\n");
                }
            }

            /*check if image input is available*/
            if (occupied(&lqueue[scit_image])) {

                /*set FPGA into buffer mode to capture image from ROE*/
                set_buffer_mode();

                /*Wake up science timeline waiting to Readout from ROE*/
                sem_post(&dma_control_sem);

                record("Dequeue new image\n");
                dma_image = dequeue(&lqueue[scit_image]);

                /*If we're simulating an image, we have to trigger a frame from the VDX*/
                if (config_values[image_sim_interface] == 0) {
                    //Trigger a frame
                    record("Trigger simulated frame\n");
                    gpio_out_state.bf.frame_trigger = 1;
                    poke_gpio(OUTPUT_GPIO_ADDR, gpio_out_state.val);
                    gpio_out_state.bf.frame_trigger = 0;
                    poke_gpio(OUTPUT_GPIO_ADDR, gpio_out_state.val);
                }

            }

        }

    }

    return NULL;
}