Exemplo n.º 1
0
/*
**  Name:	void dp_pio16_user2nic(dpeth_t *dep, int pageno, int pktsize)
**  Function:	Copies a packet from user area to board (Prog. I/O, 16bits).
*/
static void dp_pio16_user2nic(dpeth_t *dep, int pageno, int pktsize)
{
  u8_t two_bytes[2];
  phys_bytes phys_user, phys_2bytes = vir2phys(two_bytes);
  vir_bytes ecount = (pktsize + 1) & NOT(0x0001);
  int bytes, ix = 0, odd_byte = 0;
  iovec_dat_t *iovp = &dep->de_write_iovec;

  outb_reg0(dep, DP_ISR, ISR_RDC);
  dp_read_setup(dep, ecount, pageno * DP_PAGESIZE);

  do {
	bytes = iovp->iod_iovec[ix].iov_size;
	if (bytes > pktsize) bytes = pktsize;

	phys_user = numap(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_addr, bytes);
	if (!phys_user) panic(UmapErrMsg);

	if (odd_byte) {
		phys_copy(phys_user, phys_2bytes + 1, (phys_bytes) 1);
		out_word(dep->de_data_port, *(u16_t *)two_bytes);
		pktsize--;
		bytes--;
		phys_user++;
		odd_byte = 0;
		if (!bytes) continue;
	}
	ecount = bytes & NOT(0x0001);
	if (ecount != 0) {
		phys_outsw(dep->de_data_port, phys_user, ecount);
		pktsize -= ecount;
		bytes -= ecount;
		phys_user += ecount;
	}
	if (bytes) {
		phys_copy(phys_user, phys_2bytes, (phys_bytes) 1);
		pktsize--;
		bytes--;
		phys_user++;
		odd_byte = 1;
	}
	if (++ix >= IOVEC_NR) {	/* Next buffer of I/O vector */
		dp_next_iovec(iovp);
		ix = 0;
	}

  }  while (bytes > 0);

  if (odd_byte) out_word(dep->de_data_port, *(u16_t *) two_bytes);
  for (ix = 0; ix < 100; ix++) {
	if (inb_reg0(dep, DP_ISR) & ISR_RDC) break;
  }
  if (ix == 100) {
	panic(RdmaErrMsg);
  }
  return;
}
Exemplo n.º 2
0
/*
**  Name:	void dp_pio16_nic2user(dpeth_t *dep, int pageno, int pktsize)
**  Function:	Copies a packet from board to user area (Prog. I/O, 16bits).
*/
static void dp_pio16_nic2user(dpeth_t * dep, int nic_addr, int count)
{
  phys_bytes phys_user;
  vir_bytes ecount;
  int bytes, i;
  u8_t two_bytes[2];
  phys_bytes phys_2bytes;
  int odd_byte;

  ecount = (count + 1) & ~1;
  phys_2bytes = vir2phys(two_bytes);
  odd_byte = 0;

  dp_read_setup(dep, ecount, nic_addr);

  i = 0;
  while (count > 0) {
	if (i >= IOVEC_NR) {
		dp_next_iovec(iovp);
		i = 0;
		continue;
	}
	bytes = iovp->iod_iovec[i].iov_size;
	if (bytes > count) bytes = count;

	phys_user = numap(iovp->iod_proc_nr,
			  iovp->iod_iovec[i].iov_addr, bytes);
	if (!phys_user) panic(UmapErrMsg);
	if (odd_byte) {
		phys_copy(phys_2bytes + 1, phys_user, (phys_bytes) 1);
		count--;
		bytes--;
		phys_user++;
		odd_byte = 0;
		if (!bytes) continue;
	}
	ecount = bytes & ~1;
	if (ecount != 0) {
		phys_insw(dep->de_data_port, phys_user, ecount);
		count -= ecount;
		bytes -= ecount;
		phys_user += ecount;
	}
	if (bytes) {
		*(u16_t *) two_bytes = in_word(dep->de_data_port);
		phys_copy(phys_2bytes, phys_user, (phys_bytes) 1);
		count--;
		bytes--;
		phys_user++;
		odd_byte = 1;
	}
  }
  return;
}
Exemplo n.º 3
0
/*****************************************************************************
 *                                do_stat
 *************************************************************************//**
 * Perform the stat() syscall.
 * 
 * @return  On success, zero is returned. On error, -1 is returned.
 *****************************************************************************/
PUBLIC int do_stat()
{
	char pathname[MAX_PATH]; /* parameter from the caller */
	char filename[MAX_PATH]; /* directory has been stipped */

	/* get parameters from the message */
	int name_len = fs_msg.NAME_LEN;	/* length of filename */
	int src = fs_msg.source;	/* caller proc nr. */
	assert(name_len < MAX_PATH);
	phys_copy((void*)va2la(TASK_FS, pathname),    /* to   */
		  (void*)va2la(src, fs_msg.PATHNAME), /* from */
		  name_len);
	pathname[name_len] = 0;	/* terminate the string */

	int inode_nr = search_file(pathname);
	if (inode_nr == INVALID_INODE) {	/* file not found */
		printl("{FS} FS::do_stat():: search_file() returns "
		       "invalid inode: %s\n", pathname);
		return -1;
	}

	struct inode * pin = 0;

	struct inode * dir_inode;
	if (strip_path(filename, pathname, &dir_inode) != 0) {
		/* theoretically never fail here
		 * (it would have failed earlier when
		 *  search_file() was called)
		 */
		assert(0);
	}
	pin = get_inode(dir_inode->i_dev, inode_nr);

	struct stat s;		/* the thing requested */
	s.st_dev = pin->i_dev;
	s.st_ino = pin->i_num;
	s.st_mode= pin->i_mode;
	s.st_rdev= is_special(pin->i_mode) ? pin->i_start_sect : NO_DEV;
	s.st_size= pin->i_size;

	put_inode(pin);

	phys_copy((void*)va2la(src, fs_msg.BUF), /* to   */
		  (void*)va2la(TASK_FS, &s),	 /* from */
		  sizeof(struct stat));

	return 0;
}
Exemplo n.º 4
0
PRIVATE void cons_setc(const int pos, const int c)
{
    char ch;

    ch= c;
    phys_copy(vir2phys((vir_bytes)&ch), COLOR_BASE+(20*80+pos)*2, 1);
}
Exemplo n.º 5
0
PUBLIC int arch_get_params(char *params, int maxsize)
{
	phys_copy(seg2phys(mon_ds) + params_offset, vir2phys(params),
		MIN(maxsize, params_size));
	params[maxsize-1] = '\0';
	return OK;
}
Exemplo n.º 6
0
PUBLIC void arch_get_aout_headers(const int i, struct exec *h)
{
    /* The bootstrap loader created an array of the a.out headers at
     * absolute address 'aout'. Get one element to h.
     */
    phys_copy(aout + i * A_MINHDR, vir2phys(h), (phys_bytes) A_MINHDR);
}
Exemplo n.º 7
0
////复制父进程的地址空间
static int copy_mem(int pid,struct task_struct *p)
{
    struct descriptor *dp = &proc_table[pid].ldts[INDEX_LDT_C];
    int text_base = get_base(dp);
    int text_limit = get_limit(dp);
    int text_size = (text_limit + 1) * ((dp->limit_high_attr2 * 0x80)?4096:1);

    dp = &proc_table[pid].ldts[INDEX_LDT_D]; 
    int data_base =  get_base(dp);
    int data_limit= get_limit(dp);
    int data_size = (text_limit + 1) * ((dp->limit_high_attr2 * 0x80)?4096:1);

    assert((text_base == data_base)  && 
            (text_limit == data_limit) &&
            (text_size == data_size)
          );

    int child_base = alloc_mem(p->pid,text_size);

    //	printk("child_base = %d\t text_base = %d\t text_size = %d\n",child_base,text_base,text_size);
    //	memcpy((void *)child_base,(void *)(text_base),text_size);

    //	printk("child_base = %d\t text_base = %d\t text_size = %d\n",child_base,text_base,text_size);
    phys_copy((char *)child_base,(char *)(text_base),text_size);
    return child_base;
}
Exemplo n.º 8
0
Arquivo: hd.c Projeto: 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;
    }
}
Exemplo n.º 9
0
PUBLIC int arch_set_params(char *params, int size)
{
	if(size > params_size)
		return E2BIG;
	phys_copy(vir2phys(params), seg2phys(mon_ds) + params_offset, size);
	return OK;
}
Exemplo n.º 10
0
/**************************************************************************************************
 * 					msg_send
 **************************************************************************************************
 * <Ring 0> Send a message to the dest proc. If dest is blocked waiting for the message,
 * copy the message to it and unblock dest. 
 * Otherwise the caller will be blocked and appended to the dest's sending queue.
 *
 * @param current	The caller, the sender.
 * @param dest		To whom the message is sent.
 * @param msg		Pointer to the MESSAGE struct.
 *
 * @return		0 if success.
 *************************************************************************************************/
PRIVATE int msg_send(PROCESS* current, int dest, MESSAGE* msg){
	PROCESS* sender		= current;
	PROCESS* p_dest		= proc_table + dest;

	assert(proc2pid(sender) != dest);

	if(deadlock(proc2pid(sender), dest)){			/* Is there deadlock chain? */
		panic(">>DEADLOCK<< %s->%s", sender->name, p_dest->name);
	}
	/* dest is waiting for that msg or ANY msg. */
	if((p_dest->flags & RECEIVING) && (p_dest->recv_from == proc2pid(sender) || p_dest->recv_from == ANY)){
		assert(p_dest->p_msg);
		assert(msg);
		
		phys_copy(va2la(dest, p_dest->p_msg), va2la(proc2pid(sender), msg), sizeof(MESSAGE));

		p_dest->p_msg		= 0;
		p_dest->flags		&= ~RECEIVING;		/* dest has received the message */
		p_dest->recv_from	= NO_TASK;
		unblock(p_dest);

		assert(p_dest->flags == 0);
		assert(p_dest->p_msg == 0);
		assert(p_dest->recv_from == NO_TASK);
		assert(p_dest->send_to == NO_TASK);

		assert(sender->flags == 0);
		assert(sender->p_msg == 0);
		assert(sender->recv_from == NO_TASK);
		assert(sender->send_to == NO_TASK);
	}else{	/* However, dest is not waiting for the message */
		sender->flags		|= SENDING;
		assert(sender->flags == SENDING);
		sender->send_to		= dest;
		sender->p_msg		= msg;

		/* append to the sending queue */
		PROCESS* p;
		if(p_dest->q_sending){
			p = p_dest->q_sending;
			while(p->next_sending){
				p = p->next_sending;
			}
			p->next_sending = sender;
		}else{
			p_dest->q_sending = sender;
		}
		sender->next_sending = 0;
		block(sender);

		assert(sender->flags == SENDING);
		assert(sender->p_msg != 0);
		assert(sender->recv_from == NO_TASK);
		assert(sender->send_to == dest);
	}
	return 0;
}
Exemplo n.º 11
0
/*===========================================================================*
 *				intr_init				     *
 *===========================================================================*/
PUBLIC int intr_init(const int mine, const int auto_eoi)
{
/* Initialize the 8259s, finishing with all interrupts disabled.  This is
 * only done in protected mode, in real mode we don't touch the 8259s, but
 * use the BIOS locations instead.  The flag "mine" is set if the 8259s are
 * to be programmed for MINIX, or to be reset to what the BIOS expects.
 */

      /* The AT and newer PS/2 have two interrupt controllers, one master,
       * one slaved at IRQ 2.  (We don't have to deal with the PC that
       * has just one controller, because it must run in real mode.)
       */
      outb( INT_CTL, machine.ps_mca ? ICW1_PS : ICW1_AT);
      outb( INT_CTLMASK, mine == INTS_MINIX ? IRQ0_VECTOR : BIOS_IRQ0_VEC);
					/* ICW2 for master */
      outb( INT_CTLMASK, (1 << CASCADE_IRQ));
					/* ICW3 tells slaves */
      if (auto_eoi)
          outb( INT_CTLMASK, ICW4_AT_AEOI_MASTER);
      else
          outb( INT_CTLMASK, ICW4_AT_MASTER);
      outb( INT_CTLMASK, ~(1 << CASCADE_IRQ)); /* IRQ 0-7 mask */
      outb( INT2_CTL, machine.ps_mca ? ICW1_PS : ICW1_AT);
      outb( INT2_CTLMASK, mine == INTS_MINIX ? IRQ8_VECTOR : BIOS_IRQ8_VEC);
						/* ICW2 for slave */
      outb( INT2_CTLMASK, CASCADE_IRQ);	/* ICW3 is slave nr */
      if (auto_eoi)
         outb( INT2_CTLMASK, ICW4_AT_AEOI_SLAVE);
      else
         outb( INT2_CTLMASK, ICW4_AT_SLAVE);
      outb( INT2_CTLMASK, ~0);		/* IRQ 8-15 mask */

      /* Copy the BIOS vectors from the BIOS to the Minix location, so we
       * can still make BIOS calls without reprogramming the i8259s.
       */
#if IRQ0_VECTOR != BIOS_IRQ0_VEC
      phys_copy(BIOS_VECTOR(0) * 4L, VECTOR(0) * 4L, 8 * 4L);
#endif
#if IRQ8_VECTOR != BIOS_IRQ8_VEC
      phys_copy(BIOS_VECTOR(8) * 4L, VECTOR(8) * 4L, 8 * 4L);
#endif

  return OK;
}
Exemplo n.º 12
0
Arquivo: hd.c Projeto: 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;
	}
}
Exemplo n.º 13
0
/*
 * Write bytes to task address space for debugger.
 */
void
db_write_bytes(
	vm_offset_t	addr,
	int		size,
	char		*data,
	task_t		task)
{
	int		n,max;
	addr64_t	phys_dst;
	addr64_t 	phys_src;
	pmap_t	pmap;
	
	while (size > 0) {

		phys_src = db_vtophys(kernel_pmap, (vm_offset_t)data); 
		if (phys_src == 0) {
			db_printf("\nno memory is assigned to src address %08x\n",
				  data);
			db_error(0);
			/* NOTREACHED */
		}
		
		/* space stays as kernel space unless in another task */
		if (task == NULL) pmap = kernel_pmap;
		else pmap = task->map->pmap;

		phys_dst = db_vtophys(pmap, (vm_offset_t)addr);  
		if (phys_dst == 0) {
			db_printf("\nno memory is assigned to dst address %08x\n",
				  addr);
			db_error(0);
			/* NOTREACHED */
		}

		/* don't over-run any page boundaries - check src range */
		max = round_page_64(phys_src + 1) - phys_src;
		if (max > size)
			max = size;
		/* Check destination won't run over boundary either */
		n = round_page_64(phys_dst + 1) - phys_dst;
		if (n < max)
			max = n;
		size -= max;
		addr += max;
		phys_copy(phys_src, phys_dst, max);

		/* resync I+D caches */
		sync_cache64(phys_dst, max);

		phys_src += max;
		phys_dst += max;
	}
}
Exemplo n.º 14
0
/**************************************************************
 *               do_stat
 **************************************************************
	@function:get the information of a pathname
		The information we need for stat hided in the inode. So we just need to get the info of inode of pathname.
	@input:
	@return:0 if sucess
**************************************************************/
int hykdo_stat()
{
    char filename[MAX_FILENAME_LEN];
    char pathname[MAX_PATH_LEN];
    int pathname_len = fs_msg.NAME_LEN;
    int src = fs_msg.source;
//	pathname = fs_msg.PATHNAME; /*no!!! you can not do this directly! For they are not in the same address space*/
    phys_copy( (void *)va2la(TASK_FS, pathname),\
               (void *)va2la(src, fs_msg.PATHNAME),\
               fs_msg.NAME_LEN);
    pathname[pathname_len] = 0;

    int inode_nr_path = search_file(pathname);
    if(inode_nr_path == INVALID_INODE) {
        printl("[FS]:stat faild becase of invalid inode\n");
        return -1;
    }
    struct inode *dir_inode;
    if(strip_path(filename, pathname, &dir_inode)!=0) {
        assert(0);
    }
    struct inode *file_inode=get_inode(dir_inode->i_dev, inode_nr_path);

    struct stat s;
    s.dev = file_inode->i_dev;
    s.size = file_inode->i_size;
    s.mode = file_inode->i_mode;
    s.ino = file_inode->i_num;
    s.rdev = is_special(file_inode->i_mode) ? file_inode->i_start_sect: NO_DEV;

    put_inode(file_inode);

    phys_copy( (void *)va2la(src, fs_msg.BUF),\
               (void *)va2la(TASK_FS, &stat),\
               sizeof(struct stat));
    printl("fs_msg.buf.size:%x", ((struct stat *)va2la(src, fs_msg.BUF))->size);
    return 0;
}
Exemplo n.º 15
0
/**
 * Perform syslog() system call .
 *
 * @return 
 *****************************************************************************/
PUBLIC int do_disklog()
{
	char buf[STR_DEFAULT_LEN];

	/* get parameters from the message */
	int str_len = fs_msg.CNT;	/* length of filename */
	int src = fs_msg.source;	/* caller proc nr. */
	assert(str_len < STR_DEFAULT_LEN);
	phys_copy((void*)va2la(TASK_FS, buf),    /* to   */
		  (void*)va2la(src, fs_msg.BUF), /* from */
		  str_len);
	buf[str_len] = 0;	/* terminate the string */

	return disklog(buf);
}
Exemplo n.º 16
0
PRIVATE __dead void arch_bios_poweroff(void)
{
	u32_t cr0;
	
	/* Disable paging */
	cr0 = read_cr0();
	cr0 &= ~I386_CR0_PG;
	write_cr0(cr0);
	/* Copy 16-bit poweroff code to below 1M */
	phys_copy(
		(u32_t)&poweroff16,
		BIOS_POWEROFF_ENTRY,
		(u32_t)&poweroff16_end-(u32_t)&poweroff16);
	poweroff_jmp();
}
Exemplo n.º 17
0
static u32_t phys_get32(phys_bytes addr)
{
	const u32_t v;
	int r;

	if(!vm_running) {
		phys_copy(addr, vir2phys(&v), sizeof(v));
		return v;
	}

	if((r=lin_lin_copy(NULL, addr, 
		proc_addr(SYSTEM), vir2phys(&v), sizeof(v))) != OK) {
		panic("lin_lin_copy for phys_get32 failed: %d",  r);
	}

	return v;
}
Exemplo n.º 18
0
PRIVATE void hd_ioctl(MESSAGE *p)
{
    int device = p->DEVICE;
    int drive = DRV_OF_DEV(device);

    struct hd_info *hdi = &hdinfo[drive];

    if (p->REQUEST == DIOCTL_GET_GEO) {
        void *dst = va2la(p->PROC_NR, p->BUF);
        void *src = va2la(TASK_HD,
                device < MAX_PRIM ?
                &hdi->primary[device] :
                &hdi->logical[(device - MINOR_hd1a) % NR_SUB_PER_DRIVE]);
        phys_copy(dst, src, sizeof (struct part_info));
    } else {
        kprintf("[KERNEL ERROR]error ioctl cmd\n");
    }
}
Exemplo n.º 19
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;
    }
}
Exemplo n.º 20
0
/**
 * Invoked when task TTY receives DEV_WRITE message.
 * 
 * @param tty  To which TTY the calller proc is bound.
 * @param msg  The MESSAGE.
 *****************************************************************************/
PRIVATE void tty_do_write(TTY* tty, MESSAGE* msg)
{
	char buf[TTY_OUT_BUF_LEN];
	char * p = (char*)va2la(msg->PROC_NR, msg->BUF);
	int i = msg->CNT;
	int j;

	while (i) {
		int bytes = min(TTY_OUT_BUF_LEN, i);
		phys_copy(va2la(TASK_TTY, buf), (void*)p, bytes);
		for (j = 0; j < bytes; j++)
			out_char(tty->console, buf[j]);
		i -= bytes;
		p += bytes;
	}

	msg->type = SYSCALL_RET;
	send_recv(SEND, msg->source, msg);
}
Exemplo n.º 21
0
Arquivo: hd.c Projeto: cosail/lwos
/*
 * <ring 1> this routine handles the DEV_IOCTL messge.
 *
 * @param msg - message.
 */
static void hd_ioctl(MESSAGE *msg)
{
	int device = msg->DEVICE;
	int drive = DRV_OF_DEV(device);

	struct hd_info *hdi = &hd_info[drive];

	if (msg->REQUEST == DIOCTL_GET_GEO)
	{
		void *dst = va2la(msg->PROC_NR, msg->BUF);
		void *src = va2la(TASK_HD, device < MAX_PRIM ?
			&hdi->primary[device] :
			&hdi->logical[(device - MINOR_hd1a) % NR_SUB_PER_DRIVE]);
		phys_copy(dst, src, sizeof(struct part_info));
	}
	else
	{
		assert(0);
	}
}
Exemplo n.º 22
0
Arquivo: tty.c Projeto: Shelro/TJinix
/**
 * Echo the char just pressed and transfer it to the waiting process.
 * 
 * @param tty   Ptr to a TTY struct.
 *****************************************************************************/
PRIVATE void tty_dev_write(TTY* tty)
{
	while (tty->ibuf_cnt) {
		char ch = *(tty->ibuf_tail);
		tty->ibuf_tail++;
		if (tty->ibuf_tail == tty->ibuf + TTY_IN_BYTES)
			tty->ibuf_tail = tty->ibuf;
		tty->ibuf_cnt--;

		if (tty->tty_left_cnt) {
			if (ch >= ' ' && ch <= '~') { /* printable */
				out_char(tty->console, ch);

				assert(tty->tty_req_buf);
				void * p = tty->tty_req_buf +
					   tty->tty_trans_cnt;
				phys_copy(p, (void *)va2la(TASK_TTY, &ch), 1);

				tty->tty_trans_cnt++;
				tty->tty_left_cnt--;
			}
			else if (ch == '\b' && tty->tty_trans_cnt) {
				out_char(tty->console, ch);
				tty->tty_trans_cnt--;
				tty->tty_left_cnt++;
			}

			if (ch == '\n' || tty->tty_left_cnt == 0) {
				out_char(tty->console, '\n');

				assert(tty->tty_procnr != NO_TASK);
				MESSAGE msg;
				msg.type = RESUME_PROC;
				msg.PROC_NR = tty->tty_procnr;
				msg.CNT = tty->tty_trans_cnt;
				send_recv(SEND, tty->tty_caller, &msg);
				tty->tty_left_cnt = 0;
			}
		}
	}
}
Exemplo n.º 23
0
/*===========================================================================*
 *				DEBUG routines here			     * 
 *===========================================================================*/
PUBLIC void p_dmp()
{
/* Proc table dump */

  register struct proc *rp;
  char *np;
  vir_clicks base, limit, first, last;
  phys_bytes ltmp, dst;
  int index;
  int i;
  char *cp;

  printf(
  "\r\nproc    pid   pc     sp   splow  flag  user    sys  base limit  recv command\r\n");

  dst = umap(proc_addr(SYSTASK), D, (vir_bytes)nbuff, (vir_bytes)NSIZE);

  for (rp = &proc[0]; rp < &proc[NR_PROCS+NR_TASKS]; rp++)  {
	if (rp->p_flags & P_SLOT_FREE) continue;
	first = rp->p_map[T].mem_phys;
	last = rp->p_map[S].mem_phys + rp->p_map[S].mem_len;
	ltmp = ((long) first << CLICK_SHIFT) + 512L;
	base = (vir_clicks) (ltmp/1024L);
	ltmp = (((long) last << CLICK_SHIFT) + 512L);
	limit = (vir_clicks) (ltmp/1024L);
	prname((int)(rp - proc));
	printf("%4d %6X  %6X %6X %6x %4D %6D  %4dK %4dK  ",
		rp->p_pid, (long)rp->p_reg.pc,
		(long)rp->p_reg.sp, (long)rp->p_splow,
		rp->p_flags, rp->user_time, rp->sys_time,
		base, limit);
	if (rp->p_flags == 0)
		printf("      ");
	else
		prname(NR_TASKS + rp->p_getfrom);

	/* Fetch the command string from the user process. */
	index = (int)(rp - proc) - NR_TASKS;
	if (index > LOW_USER && aout[index] != 0) {
		phys_copy(aout[index], dst, (long) NSIZE);
		nbuff[NSIZE] = 0;
		for (np = &nbuff[0]; np < &nbuff[NSIZE]; np++)
			if (*np <= ' ' || *np >= 0177) *np = 0;
		if (index == LOW_USER + 1)
			cp = "/bin/sh";
		else
			cp = nbuff;
		for(i=0;i<100;i++) 
			if(cp[i] == '\0')
				break;
		if(i > 6)
			printf("\r\n\t");
		printf("%s", cp);
	}
	printf("\r\n");
  }
#ifdef NEEDED
  printf("\r\nproc    callq sendlk mesbuf from nready pend blkd held alarm\r\n");
  for (rp = &proc[0]; rp < &proc[NR_PROCS+NR_TASKS]; rp++)  {
	if (rp->p_flags & P_SLOT_FREE) continue;
	prname((int)(rp - proc));
	printf(" %6X %6X %6X %4d %6X %4d %4d %4d %X\r\n",
		rp->p_callerq,
		rp->p_sendlink,
		rp->p_messbuf,
		rp->p_getfrom,
		rp->p_nextready,
		rp->p_pending,
		rp->p_int_blocked,
		rp->p_int_held,
		rp->p_alarm
	);
  }
  for (index = 0; index < NQ; index++) {
	printf("q=%d: ", index);
	for (rp = rdy_head[index]; rp != NIL_PROC; rp = rp->p_nextready)
		printf(" %d", (int)(rp-proc));
	printf("\r\n");
  }
  printf("held_head = 0x%X\r\n", held_head);
#endif NEEDED
  printf("\r\n");
}
Exemplo n.º 24
0
/**
 * <Ring 0> Try to get a message from the src proc. If src is blocked sending
 * the message, copy the message from it and unblock src. Otherwise the caller
 * will be blocked.
 * 
 * @param current The caller, the proc who wanna receive.
 * @param src     From whom the message will be received.
 * @param m       The message ptr to accept the message.
 * 
 * @return  Zero if success.
 *****************************************************************************/
PRIVATE int msg_receive(struct proc* current, int src, MESSAGE* m)
{
	struct proc* p_who_wanna_recv = current; /**
						  * This name is a little bit
						  * wierd, but it makes me
						  * think clearly, so I keep
						  * it.
						  */
	struct proc* p_from = 0; /* from which the message will be fetched */
	struct proc* prev = 0;
	int copyok = 0;

	assert(proc2pid(p_who_wanna_recv) != src);

	if ((p_who_wanna_recv->has_int_msg) &&
	    ((src == ANY) || (src == INTERRUPT))) {
		/* There is an interrupt needs p_who_wanna_recv's handling and
		 * p_who_wanna_recv is ready to handle it.
		 */

		MESSAGE msg;
		reset_msg(&msg);
		msg.source = INTERRUPT;
		msg.type = HARD_INT;
		assert(m);
		phys_copy(va2la(proc2pid(p_who_wanna_recv), m), &msg,
			  sizeof(MESSAGE));

		p_who_wanna_recv->has_int_msg = 0;

		assert(p_who_wanna_recv->p_flags == 0);
		assert(p_who_wanna_recv->p_msg == 0);
		assert(p_who_wanna_recv->p_sendto == NO_TASK);
		assert(p_who_wanna_recv->has_int_msg == 0);

		return 0;
	}


	/* Arrives here if no interrupt for p_who_wanna_recv. */
	if (src == ANY) {
		/* p_who_wanna_recv is ready to receive messages from
		 * ANY proc, we'll check the sending queue and pick the
		 * first proc in it.
		 */
		if (p_who_wanna_recv->q_sending) {
			p_from = p_who_wanna_recv->q_sending;
			copyok = 1;

			assert(p_who_wanna_recv->p_flags == 0);
			assert(p_who_wanna_recv->p_msg == 0);
			assert(p_who_wanna_recv->p_recvfrom == NO_TASK);
			assert(p_who_wanna_recv->p_sendto == NO_TASK);
			assert(p_who_wanna_recv->q_sending != 0);
			assert(p_from->p_flags == SENDING);
			assert(p_from->p_msg != 0);
			assert(p_from->p_recvfrom == NO_TASK);
			assert(p_from->p_sendto == proc2pid(p_who_wanna_recv));
		}
	}
	else {
		/* p_who_wanna_recv wants to receive a message from
		 * a certain proc: src.
		 */
		p_from = &proc_table[src];

		if ((p_from->p_flags & SENDING) &&
		    (p_from->p_sendto == proc2pid(p_who_wanna_recv))) {
			/* Perfect, src is sending a message to
			 * p_who_wanna_recv.
			 */
			copyok = 1;

			struct proc* p = p_who_wanna_recv->q_sending;
			assert(p); /* p_from must have been appended to the
				    * queue, so the queue must not be NULL
				    */
			while (p) {
				assert(p_from->p_flags & SENDING);
				if (proc2pid(p) == src) { /* if p is the one */
					p_from = p;
					break;
				}
				prev = p;
				p = p->next_sending;
			}

			assert(p_who_wanna_recv->p_flags == 0);
			assert(p_who_wanna_recv->p_msg == 0);
			assert(p_who_wanna_recv->p_recvfrom == NO_TASK);
			assert(p_who_wanna_recv->p_sendto == NO_TASK);
			assert(p_who_wanna_recv->q_sending != 0);
			assert(p_from->p_flags == SENDING);
			assert(p_from->p_msg != 0);
			assert(p_from->p_recvfrom == NO_TASK);
			assert(p_from->p_sendto == proc2pid(p_who_wanna_recv));
		}
	}

	if (copyok) {
		/* It's determined from which proc the message will
		 * be copied. Note that this proc must have been
		 * waiting for this moment in the queue, so we should
		 * remove it from the queue.
		 */
		if (p_from == p_who_wanna_recv->q_sending) { /* the 1st one */
			assert(prev == 0);
			p_who_wanna_recv->q_sending = p_from->next_sending;
			p_from->next_sending = 0;
		}
		else {
			assert(prev);
			prev->next_sending = p_from->next_sending;
			p_from->next_sending = 0;
		}

		assert(m);
		assert(p_from->p_msg);
		/* copy the message */
		phys_copy(va2la(proc2pid(p_who_wanna_recv), m),
			  va2la(proc2pid(p_from), p_from->p_msg),
			  sizeof(MESSAGE));

		p_from->p_msg = 0;
		p_from->p_sendto = NO_TASK;
		p_from->p_flags &= ~SENDING;
		unblock(p_from);
	}
	else {  /* nobody's sending any msg */
		/* Set p_flags so that p_who_wanna_recv will not
		 * be scheduled until it is unblocked.
		 */
		p_who_wanna_recv->p_flags |= RECEIVING;

		p_who_wanna_recv->p_msg = m;

		if (src == ANY)
			p_who_wanna_recv->p_recvfrom = ANY;
		else
			p_who_wanna_recv->p_recvfrom = proc2pid(p_from);

		block(p_who_wanna_recv);

		assert(p_who_wanna_recv->p_flags == RECEIVING);
		assert(p_who_wanna_recv->p_msg != 0);
		assert(p_who_wanna_recv->p_recvfrom != NO_TASK);
		assert(p_who_wanna_recv->p_sendto == NO_TASK);
		assert(p_who_wanna_recv->has_int_msg == 0);
	}

	return 0;
}
Exemplo n.º 25
0
/**
 * <Ring 0> Send a message to the dest proc. If dest is blocked waiting for
 * the message, copy the message to it and unblock dest. Otherwise the caller
 * will be blocked and appended to the dest's sending queue.
 * 
 * @param current  The caller, the sender.
 * @param dest     To whom the message is sent.
 * @param m        The message.
 * 
 * @return Zero if success.
 *****************************************************************************/
PRIVATE int msg_send(struct proc* current, int dest, MESSAGE* m)
{
	struct proc* sender = current;
	struct proc* p_dest = proc_table + dest; /* proc dest */

	assert(proc2pid(sender) != dest);

	/* check for deadlock here */
	if (deadlock(proc2pid(sender), dest)) {
		panic(">>DEADLOCK<< %s->%s", sender->name, p_dest->name);
	}

	if ((p_dest->p_flags & RECEIVING) && /* dest is waiting for the msg */
	    (p_dest->p_recvfrom == proc2pid(sender) ||
	     p_dest->p_recvfrom == ANY)) {
		assert(p_dest->p_msg);
		assert(m);

		phys_copy(va2la(dest, p_dest->p_msg),
			  va2la(proc2pid(sender), m),
			  sizeof(MESSAGE));
		p_dest->p_msg = 0;
		p_dest->p_flags &= ~RECEIVING; /* dest has received the msg */
		p_dest->p_recvfrom = NO_TASK;
		unblock(p_dest);

		assert(p_dest->p_flags == 0);
		assert(p_dest->p_msg == 0);
		assert(p_dest->p_recvfrom == NO_TASK);
		assert(p_dest->p_sendto == NO_TASK);
		assert(sender->p_flags == 0);
		assert(sender->p_msg == 0);
		assert(sender->p_recvfrom == NO_TASK);
		assert(sender->p_sendto == NO_TASK);
	}
	else { /* dest is not waiting for the msg */
		sender->p_flags |= SENDING;
		assert(sender->p_flags == SENDING);
		sender->p_sendto = dest;
		sender->p_msg = m;

		/* append to the sending queue */
		struct proc * p;
		if (p_dest->q_sending) {
			p = p_dest->q_sending;
			while (p->next_sending)
				p = p->next_sending;
			p->next_sending = sender;
		}
		else {
			p_dest->q_sending = sender;
		}
		sender->next_sending = 0;

		block(sender);

		assert(sender->p_flags == SENDING);
		assert(sender->p_msg != 0);
		assert(sender->p_recvfrom == NO_TASK);
		assert(sender->p_sendto == dest);
	}

	return 0;
}
Exemplo n.º 26
0
/**
 * Read/Write file and return byte count read/written.
 *
 * Sector map is not needed to update, since the sectors for the file have been
 * allocated and the bits are set when the file was created.
 * 
 * @return How many bytes have been read/written.
 *****************************************************************************/
PUBLIC int do_rdwt()
{
	int fd = fs_msg.FD;	/**< file descriptor. */
	void * buf = fs_msg.BUF;/**< r/w buffer */
	int len = fs_msg.CNT;	/**< r/w bytes */

	int src = fs_msg.source;		/* caller proc nr. */

	assert((pcaller->filp[fd] >= &f_desc_table[0]) &&
	       (pcaller->filp[fd] < &f_desc_table[NR_FILE_DESC]));

	if (!(pcaller->filp[fd]->fd_mode & O_RDWR))
		return -1;

	int pos = pcaller->filp[fd]->fd_pos;

	struct inode * pin = pcaller->filp[fd]->fd_inode;

	assert(pin >= &inode_table[0] && pin < &inode_table[NR_INODE]);

	int imode = pin->i_mode & I_TYPE_MASK;

	if (imode == I_CHAR_SPECIAL) {
		int t = fs_msg.type == READ ? DEV_READ : DEV_WRITE;
		fs_msg.type = t;

		int dev = pin->i_start_sect;
		assert(MAJOR(dev) == 4);

		fs_msg.DEVICE	= MINOR(dev);
		fs_msg.BUF	= buf;
		fs_msg.CNT	= len;
		fs_msg.PROC_NR	= src;
		assert(dd_map[MAJOR(dev)].driver_nr != INVALID_DRIVER);
		send_recv(BOTH, dd_map[MAJOR(dev)].driver_nr, &fs_msg);
		assert(fs_msg.CNT == len);

		return fs_msg.CNT;
	}
	else {
		assert(pin->i_mode == I_REGULAR || pin->i_mode == I_DIRECTORY);
		assert((fs_msg.type == READ) || (fs_msg.type == WRITE));

		//讀寫不能超過檔案大小
		int pos_end;
		if (fs_msg.type == READ)
			pos_end = min(pos + len, pin->i_size);
		else		/* WRITE */
			pos_end = min(pos + len, pin->i_nr_sects * SECTOR_SIZE);


		//secNum的offset
		int off = pos % SECTOR_SIZE;

		//哪一個sector
		int rw_sect_min=pin->i_start_sect+(pos>>SECTOR_SIZE_SHIFT);

		//結束在那個sector
		int rw_sect_max=pin->i_start_sect+(pos_end>>SECTOR_SIZE_SHIFT);

		//扇區讀寫使用chunk為單位,如果一次buf傳的完的話,就使用rw_sect_max - rw_sect_min + 1
		int chunk = min(rw_sect_max - rw_sect_min + 1,
				FSBUF_SIZE >> SECTOR_SIZE_SHIFT);

		int bytes_rw = 0;
		int bytes_left = len;
		int i;

		for (i = rw_sect_min; i <= rw_sect_max; i += chunk) {
			/* read/write this amount of bytes every time */
			int bytes = min(bytes_left, chunk * SECTOR_SIZE - off);
			rw_sector(DEV_READ,
				  pin->i_dev,
				  i * SECTOR_SIZE,
				  chunk * SECTOR_SIZE,
				  TASK_FS,
				  fsbuf);

			if (fs_msg.type == READ) {
				phys_copy((void*)va2la(src, buf + bytes_rw),
					  (void*)va2la(TASK_FS, fsbuf + off),
					  bytes);
			}
			else {	/* WRITE */
				phys_copy((void*)va2la(TASK_FS, fsbuf + off),
					  (void*)va2la(src, buf + bytes_rw),
					  bytes);

				rw_sector(DEV_WRITE,
					  pin->i_dev,
					  i * SECTOR_SIZE,
					  chunk * SECTOR_SIZE,
					  TASK_FS,
					  fsbuf);
			}
			off = 0;
			bytes_rw += bytes;
			pcaller->filp[fd]->fd_pos += bytes;
			bytes_left -= bytes;
		}

		if (pcaller->filp[fd]->fd_pos > pin->i_size) {
			/* update inode::size */
			pin->i_size = pcaller->filp[fd]->fd_pos;

			/* write the updated i-node back to disk */
			sync_inode(pin);
		}

		return bytes_rw;
	}
}
Exemplo n.º 27
0
PUBLIC int do_open()
{
    int i = 0;
    int fd = -1; // return value
    char pathname[MAX_PATH];

    int flags = fs_msg.FLAGS;
    int name_len = fs_msg.NAME_LEN;
    int src = fs_msg.source;

    assert(name_len < MAX_PATH);
    phys_copy(
        (void *)va2la(TASK_FS, pathname),
        (void *)va2la(src, fs_msg.PATHNAME),
        name_len
    );
    pathname[name_len] = 0;

    /* 先在调用者进程中查找空闲文件描述符 */
    for (i = 0; i < NR_FILES; i++)
        if (pcaller->filp[i] == 0) {
            fd = i;
            break;
        }
    if ((fd < 0) || (fd >= NR_FILES))
        panic("filp[] is full (PID:%d)", proc2pid(pcaller));

    /* 然后在 f_desc_table 中查找空闲位置 */
    for (i = 0; i < NR_FILE_DESC; i++)
        if (f_desc_table[i].fd_inode == 0)
            break;
    if (i >= NR_FILE_DESC)
        panic("f_desc_table[] is full (PID:%d)", proc2pid(pcaller));

    /* 在磁盘中查找文件 */
    int inode_nr = search_file(pathname);

    /* 准备创建或打开文件 */
    struct inode *pin = 0;
    if (flags & O_CREAT) {
        if (inode_nr) {
            printl("file exists.\n");
            return -1;
        }
        else { // 文件不存在且标志位 O_CREAT
            pin = creat_file(pathname, flags);
        }
    }
    else {
        assert(flags & O_RDWR);

        char filename[MAX_PATH];
        struct inode * dir_inode;
        if (strip_path(filename, pathname, &dir_inode) != 0)
            return -1;
        pin = get_inode(dir_inode->i_dev, inode_nr);
    }

    /* 关联文件描述符 */
    if (pin) {
        /* proc <- fd (connects proc with file_descriptor) */
        pcaller->filp[fd] = &f_desc_table[i];

        /* fd <- inode (connects file_descriptor with inode) */
        f_desc_table[i].fd_mode = flags;
        f_desc_table[i].fd_pos = 0;
        f_desc_table[i].fd_inode = pin;

        int imode = pin->i_mode & I_TYPE_MASK;
        if (imode == I_CHAR_SPECIAL) {
            MESSAGE driver_msg;

            driver_msg.type = DEV_OPEN;
            int dev = pin->i_start_sect;
            driver_msg.DEVICE = MINOR(dev);
            assert(MAJOR(dev) == 4);
            assert(dd_map[MAJOR(dev)].driver_nr != INVALID_DRIVER);

            /* 如果是字符设备则交给该设备的驱动处理 */
            send_recv(BOTH, dd_map[MAJOR(dev)].driver_nr, &driver_msg);
        }
        else if (imode == I_DIRECTORY)
            assert(pin->i_num == ROOT_INODE);
        else
            assert(pin->i_mode == I_REGULAR);
    }
    else
        return -1; // open file failed

    return fd;
}
Exemplo n.º 28
0
Arquivo: open.c Projeto: kong123/STUDY
/**
 * Open a file and return the file descriptor.
 *
 * @return File descriptor if successful, otherwise a negative error code.
 *****************************************************************************/
PUBLIC int do_open()
{
    int fd = -1;		/* return value */

    char pathname[MAX_PATH];

    /* get parameters from the message */
    int flags = fs_msg.FLAGS;	/* access mode */
    int name_len = fs_msg.NAME_LEN;	/* length of filename */
    int src = fs_msg.source;	/* caller proc nr. */
    assert(name_len < MAX_PATH);
    phys_copy((void*)va2la(TASK_FS, pathname),
              (void*)va2la(src, fs_msg.PATHNAME),
              name_len);
    pathname[name_len] = 0;

    /* find a free slot in PROCESS::filp[] */
    int i;
    for (i = 0; i < NR_FILES; i++) {
        if (pcaller->filp[i] == 0) {
            fd = i;
            break;
        }
    }
    if ((fd < 0) || (fd >= NR_FILES))
        panic("filp[] is full (PID:%d)", proc2pid(pcaller));

    /* find a free slot in f_desc_table[] */
    for (i = 0; i < NR_FILE_DESC; i++)
        if (f_desc_table[i].fd_inode == 0)
            break;
    if (i >= NR_FILE_DESC)
        panic("f_desc_table[] is full (PID:%d)", proc2pid(pcaller));

    int inode_nr = search_file(pathname);

    struct inode * pin = 0;
    if (flags & O_CREAT) {
        if (inode_nr) {
            printl("file exists.\n");
            return -1;
        }
        else {
            pin = create_file(pathname, flags);
        }
    }
    else {
        assert(flags & O_RDWR);

        char filename[MAX_PATH];
        struct inode * dir_inode;
        if (strip_path(filename, pathname, &dir_inode) != 0)
            return -1;
        pin = get_inode(dir_inode->i_dev, inode_nr);
    }

    if (pin) {
        /* connects proc with file_descriptor */
        pcaller->filp[fd] = &f_desc_table[i];

        /* connects file_descriptor with inode */
        f_desc_table[i].fd_inode = pin;

        f_desc_table[i].fd_mode = flags;
        /* f_desc_table[i].fd_cnt = 1; */
        f_desc_table[i].fd_pos = 0;

        int imode = pin->i_mode & I_TYPE_MASK;

        if (imode == I_CHAR_SPECIAL) {
            MESSAGE driver_msg;
            driver_msg.type = DEV_OPEN;
            int dev = pin->i_start_sect;
            driver_msg.DEVICE = MINOR(dev);
            assert(MAJOR(dev) == 4);
            assert(dd_map[MAJOR(dev)].driver_nr != INVALID_DRIVER);
            send_recv(BOTH,
                      dd_map[MAJOR(dev)].driver_nr,
                      &driver_msg);
        }
        else if (imode == I_DIRECTORY) {
            assert(pin->i_num == ROOT_INODE);
        }
        else {
            assert(pin->i_mode == I_REGULAR);
        }
    }
    else {
        return -1;
    }

    return fd;
}
Exemplo n.º 29
0
/*===========================================================================*
 *                                   main                                    *
 *===========================================================================*/
PUBLIC void main()
{
/* Start the ball rolling. */

  register struct proc *rp;
  register int t;
  int hdrindex;
  phys_clicks text_base;
  vir_clicks text_clicks;
  vir_clicks data_clicks;
  phys_bytes phys_b;
  reg_t ktsb;			/* kernel task stack base */
  struct memory *memp;
  struct tasktab *ttp;
  struct exec e_hdr;

  licznik_elementow = 0;

  /* Initialize the interrupt controller. */
  intr_init(1);

  /* Interpret memory sizes. */
  mem_init();

  /* Clear the process table.
   * Set up mappings for proc_addr() and proc_number() macros.
   */
  for (rp = BEG_PROC_ADDR, t = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++t) {
	rp->p_nr = t;		/* proc number from ptr */
        (pproc_addr + NR_TASKS)[t] = rp;        /* proc ptr from number */
  }

  /* Resolve driver selections in the task table. */
  mapdrivers();

  /* Set up proc table entries for tasks and servers.  The stacks of the
   * kernel tasks are initialized to an array in data space.  The stacks
   * of the servers have been added to the data segment by the monitor, so
   * the stack pointer is set to the end of the data segment.  All the
   * processes are in low memory on the 8086.  On the 386 only the kernel
   * is in low memory, the rest is loaded in extended memory.
   */

  /* Task stacks. */
  ktsb = (reg_t) t_stack;

  for (t = -NR_TASKS; t <= LOW_USER; ++t) {
	rp = proc_addr(t);			/* t's process slot */
	ttp = &tasktab[t + NR_TASKS];		/* t's task attributes */
	strcpy(rp->p_name, ttp->name);
	if (t < 0) {
		if (ttp->stksize > 0) {
			rp->p_stguard = (reg_t *) ktsb;
			*rp->p_stguard = STACK_GUARD;
		}
		ktsb += ttp->stksize;
		rp->p_reg.sp = ktsb;
		text_base = code_base >> CLICK_SHIFT;
					/* tasks are all in the kernel */
		hdrindex = 0;		/* and use the first a.out header */
		rp->p_priority = PPRI_TASK;
	} else {
		hdrindex = 1 + t;	/* MM, FS, INIT follow the kernel */
		rp->p_priority = t < LOW_USER ? PPRI_SERVER : PPRI_USER;
	}

	/* The bootstrap loader has created an array of the a.out headers at
	 * absolute address 'aout'.
	 */
	phys_copy(aout + hdrindex * A_MINHDR, vir2phys(&e_hdr),
							(phys_bytes) A_MINHDR);
	text_base = e_hdr.a_syms >> CLICK_SHIFT;
	text_clicks = (e_hdr.a_text + CLICK_SIZE-1) >> CLICK_SHIFT;
	if (!(e_hdr.a_flags & A_SEP)) text_clicks = 0;	/* Common I&D */
	data_clicks = (e_hdr.a_total + CLICK_SIZE-1) >> CLICK_SHIFT;
	rp->p_map[T].mem_phys = text_base;
	rp->p_map[T].mem_len  = text_clicks;
	rp->p_map[D].mem_phys = text_base + text_clicks;
	rp->p_map[D].mem_len  = data_clicks;
	rp->p_map[S].mem_phys = text_base + text_clicks + data_clicks;
	rp->p_map[S].mem_vir  = data_clicks;	/* empty - stack is in data */

	/* Remove server memory from the free memory list.  The boot monitor
	 * promises to put processes at the start of memory chunks.
	 */
	for (memp = mem; memp < &mem[NR_MEMS]; memp++) {
		if (memp->base == text_base) {
			memp->base += text_clicks + data_clicks;
			memp->size -= text_clicks + data_clicks;
		}
	}

	/* Set initial register values. */
	rp->p_reg.pc = (reg_t) ttp->initial_pc;
	rp->p_reg.psw = istaskp(rp) ? INIT_TASK_PSW : INIT_PSW;

	if (t >= 0) {
		/* Initialize the server stack pointer.  Take it down one word
		 * to give crtso.s something to use as "argc".
		 */
		rp->p_reg.sp = (rp->p_map[S].mem_vir +
				rp->p_map[S].mem_len) << CLICK_SHIFT;
		rp->p_reg.sp -= sizeof(reg_t);
	}

	if (!isidlehardware(t)) lock_ready(rp);	/* IDLE, HARDWARE neveready */
	rp->p_flags = 0;

	alloc_segments(rp);
  }
Exemplo n.º 30
0
PUBLIC __dead void arch_shutdown(int how)
{
	u16_t magic;
	vm_stop();

	/* Mask all interrupts, including the clock. */
	outb( INT_CTLMASK, ~0);

	if(minix_panicing) {
		unsigned char unused_ch;
		/* We're panicing? Then retrieve and decode currently
		 * loaded segment selectors.
		 */
		printseg("cs: ", 1, get_cpulocal_var(proc_ptr), read_cs());
		printseg("ds: ", 0, get_cpulocal_var(proc_ptr), read_ds());
		if(read_ds() != read_ss()) {
			printseg("ss: ", 0, NULL, read_ss());
		}

		/* Printing is done synchronously over serial. */
		if (do_serial_debug)
			reset();

		/* Print accumulated diagnostics buffer and reset. */
		mb_cls();
		mb_print("Minix panic. System diagnostics buffer:\n\n");
		mb_print(kmess_buf);
		mb_print("\nSystem has panicked, press any key to reboot");
		while (!mb_read_char(&unused_ch))
			;
		reset();
	}

#if USE_BOOTPARAM
	if (how == RBT_DEFAULT) {
		how = mon_return ? RBT_HALT : RBT_RESET;
	}

	if(how != RBT_RESET) {
		/* return to boot monitor */

		outb( INT_CTLMASK, 0);            
		outb( INT2_CTLMASK, 0);
        
		/* Return to the boot monitor. Set
		 * the program if not already done.
		 */
		if (how != RBT_MONITOR)
			arch_set_params("", 1);

		if (mon_return)
			arch_monitor();

		/* monitor command with no monitor: reset or poweroff 
		 * depending on the parameters
		 */
		if (how == RBT_MONITOR) {
			how = RBT_RESET;
		}
	}

	switch (how) {
		case RBT_REBOOT:
		case RBT_RESET:
			/* Reset the system by forcing a processor shutdown. 
			 * First stop the BIOS memory test by setting a soft
			 * reset flag.
			 */
			magic = STOP_MEM_CHECK;
			phys_copy(vir2phys(&magic), SOFT_RESET_FLAG_ADDR,
       		 	SOFT_RESET_FLAG_SIZE);
			reset();
			NOT_REACHABLE;

		case RBT_HALT:
			/* Poweroff without boot monitor */
			arch_bios_poweroff();
			NOT_REACHABLE;

		case RBT_PANIC:
			/* Allow user to read panic message */
			for (; ; ) halt_cpu();
			NOT_REACHABLE;

		default:	
			/* Not possible! trigger panic */
			assert(how != RBT_MONITOR);
			assert(how != RBT_DEFAULT);
			assert(how < RBT_INVALID);
			panic("unexpected value for how: %d", how);
			NOT_REACHABLE;
	}
#else /* !USE_BOOTPARAM */
	/* Poweroff without boot monitor */
	arch_bios_poweroff();
#endif

	NOT_REACHABLE;
}