kernel/muxx_memsvc.c
/*
** Setup the shared memory space for a new task
*/
Setup the shared memory space for a new task
Setup the shared memory space for a new task
int muxx_setup_taskmem (PTCB task) {
  PMMCB mcb = NULL;
  int tsize=0;
  int ssize=0;
  int ttype=0;
  int rc = EOK;
  int i=0;
  WORD endalloc=0;
  WORD wpdr=0;
  WORD tucbsize = sizeof(struct TUCB_S);
  PTUCB ptucb = NULL;
  tucbsize = (tucbsize-1)/64;
  tucbsize = (tucbsize+1)*64;
  ttype = (task->taskType & 0000007);
  tsize = (task->taskType & 0000070);          
  ssize = (task->taskType & 0000700);          
  if (ssize != TSZ_SMALLS) return EINVVAL;      
  switch(ttype) {
  case SYS_TASK:         
    break;
  case USR_TASK:         
    break;
  case DRV_TASK:         
    if (tsize == TSZ_BIG) return EINVVAL;
    break;
  default:
    return EINVVAL;
  }
  if (task->privileges.prvflags.operprv) {
    wpdr = PDR_ACC_RW | PDR_SIZ_8K;
  } else {
    wpdr = PDR_ACC_RO | PDR_SIZ_8K;
  }
  task->mmuState.upar[0] = 0;
  task->mmuState.updr[0] = wpdr;
  task->mmuState.kpar[0] = 0;
  task->mmuState.kpdr[0] = PDR_ACC_RW | PDR_SIZ_8K;
  task->mmuState.upar[1] = 0200;
  task->mmuState.updr[1] = wpdr;
  task->mmuState.kpar[1] = 0200;
  task->mmuState.kpdr[1] = PDR_ACC_RW | PDR_SIZ_8K;
  task->mmuState.upar[2] = 0400;
  task->mmuState.updr[2] = wpdr;
  task->mmuState.kpar[2] = 0400;
  task->mmuState.kpdr[2] = PDR_ACC_RW | PDR_SIZ_8K;
  mcb = muxx_mem_getblock(task, 0200, 0, 3);
  if (mcb != NULL) {
    task->mmuState.upar[3] = mcb->blockAddr;
    task->mmuState.updr[3] = PDR_ACC_RW | PDR_SIZ_8K;
    task->mmuState.kpar[3] = mcb->blockAddr;
    task->mmuState.kpdr[3] = PDR_ACC_RW | PDR_SIZ_8K;
    endalloc = (WORD) 8192*4;
  } else {
    kprintf("Error allocating memory for page 3, PID %o\n", task);
    return (ENOMEM);
  }
  if ((tsize == TSZ_MED) || (tsize == TSZ_BIG)) {
    mcb = muxx_mem_getblock(task, 0200, 0, 4);
    if (mcb != NULL) {
      task->mmuState.upar[4] = mcb->blockAddr;
      task->mmuState.updr[4] = PDR_ACC_RW | PDR_SIZ_8K;
      task->mmuState.kpar[4] = mcb->blockAddr;
      task->mmuState.kpdr[4] = PDR_ACC_RW | PDR_SIZ_8K;
      endalloc = (WORD) 8192*5;
    } else {
      kprintf("Error allocating memory for page 4, PID %o\n", task);
      return (ENOMEM);
    }
  }
  if (tsize == TSZ_BIG) {
    mcb = muxx_mem_getblock(task, 0200, 0, 5);
    if (mcb != NULL) {
      task->mmuState.upar[5] = mcb->blockAddr;
      task->mmuState.updr[5] = PDR_ACC_RW | PDR_SIZ_8K;
      task->mmuState.kpar[5] = mcb->blockAddr;
      task->mmuState.kpdr[5] = PDR_ACC_RW | PDR_SIZ_8K;
      endalloc = (WORD) 8192*6;
    } else {
      kprintf("Error allocating memory for page 5, PID %o\n", task);
      return (ENOMEM);
    }
  }
  ptucb = (PTUCB) (endalloc - tucbsize);
  task->taskTUCB = ptucb;
  mcb = muxx_mem_getblock(task, 0100, MMCB_FLG_STK, 6);
  if (mcb != NULL) {
    task->mmuState.upar[6] = mcb->blockAddr-0100;
    task->mmuState.updr[6] = PDR_ACC_RW | PDR_SIZ_4K | PDR_DIR_DN;
    task->mmuState.kpar[6] = mcb->blockAddr-0100;
    task->mmuState.kpdr[6] = PDR_ACC_RW | PDR_SIZ_4K | PDR_DIR_DN;
  } else {
    return (ENOMEM);
  }
  task->mmuState.kpar[7] = 07600;
  task->mmuState.kpdr[7] = PDR_ACC_RW | PDR_SIZ_8K;
  if (task->privileges.prvflags.ioprv || task->privileges.prvflags.operprv) {
    task->mmuState.upar[7] = 07600;
    task->mmuState.updr[7] = PDR_ACC_RW | PDR_SIZ_8K;
  } else if (task->privileges.prvflags.auditprv) {
    task->mmuState.upar[7] = 07600;
    task->mmuState.updr[7] = PDR_ACC_RO | PDR_SIZ_8K;
  } else {
    task->mmuState.upar[7] = 0;
    task->mmuState.updr[7] = PDR_ACC_NA | PDR_SIZ_0K;
  }
  if (ttype == DRV_TASK) {
    mcb = muxx_mem_getblock(task, DRV_BUFSIZ/64, MMCB_FLG_BUF, 5);
    if (mcb != NULL) {
      task->mmuState.upar[4] = mcb->blockAddr;
      task->mmuState.updr[4] = PDR_ACC_RW | PDR_SIZ_1K;
      task->mmuState.kpar[4] = mcb->blockAddr;
      task->mmuState.kpdr[4] = PDR_ACC_RW | PDR_SIZ_1K;
    } else {
      return (ENOMEM);
    }
  }
  return (rc);
}
int muxx_setup_taskmem ( PTCB task ) { PMMCB mcb = NULL ; int tsize = 0 ; int ssize = 0 ; int ttype = 0 ; int rc = EOK ; int i = 0 ; WORD endalloc = 0 ; WORD wpdr = 0 ; WORD tucbsize = sizeof ( struct TUCB_S ) ; PTUCB ptucb = NULL ; tucbsize = ( tucbsize - 1 ) / 64 ; tucbsize = ( tucbsize + 1 ) * 64 ; ttype = ( task -> taskType & 0000007 ) ; tsize = ( task -> taskType & 0000070 ) ; ssize = ( task -> taskType & 0000700 ) ; if ( ssize != TSZ_SMALLS ) return EINVVAL ; switch ( ttype ) { case SYS_TASK : break ; case USR_TASK : break ; case DRV_TASK : if ( tsize == TSZ_BIG ) return EINVVAL ; break ; default : return EINVVAL ; } if ( task -> privileges . prvflags . operprv ) { wpdr = PDR_ACC_RW | PDR_SIZ_8K ; } else { wpdr = PDR_ACC_RO | PDR_SIZ_8K ; } task -> mmuState . upar [ 0 ] = 0 ; task -> mmuState . updr [ 0 ] = wpdr ; task -> mmuState . kpar [ 0 ] = 0 ; task -> mmuState . kpdr [ 0 ] = PDR_ACC_RW | PDR_SIZ_8K ; task -> mmuState . upar [ 1 ] = 0200 ; task -> mmuState . updr [ 1 ] = wpdr ; task -> mmuState . kpar [ 1 ] = 0200 ; task -> mmuState . kpdr [ 1 ] = PDR_ACC_RW | PDR_SIZ_8K ; task -> mmuState . upar [ 2 ] = 0400 ; task -> mmuState . updr [ 2 ] = wpdr ; task -> mmuState . kpar [ 2 ] = 0400 ; task -> mmuState . kpdr [ 2 ] = PDR_ACC_RW | PDR_SIZ_8K ; mcb = muxx_mem_getblock ( task , 0200 , 0 , 3 ) ; if ( mcb != NULL ) { task -> mmuState . upar [ 3 ] = mcb -> blockAddr ; task -> mmuState . updr [ 3 ] = PDR_ACC_RW | PDR_SIZ_8K ; task -> mmuState . kpar [ 3 ] = mcb -> blockAddr ; task -> mmuState . kpdr [ 3 ] = PDR_ACC_RW | PDR_SIZ_8K ; endalloc = ( WORD ) 8192 * 4 ; } else { kprintf ( " \n " , task ) ; return ( ENOMEM ) ; } if ( ( tsize == TSZ_MED ) || ( tsize == TSZ_BIG ) ) { mcb = muxx_mem_getblock ( task , 0200 , 0 , 4 ) ; if ( mcb != NULL ) { task -> mmuState . upar [ 4 ] = mcb -> blockAddr ; task -> mmuState . updr [ 4 ] = PDR_ACC_RW | PDR_SIZ_8K ; task -> mmuState . kpar [ 4 ] = mcb -> blockAddr ; task -> mmuState . kpdr [ 4 ] = PDR_ACC_RW | PDR_SIZ_8K ; endalloc = ( WORD ) 8192 * 5 ; } else { kprintf ( " \n " , task ) ; return ( ENOMEM ) ; } } if ( tsize == TSZ_BIG ) { mcb = muxx_mem_getblock ( task , 0200 , 0 , 5 ) ; if ( mcb != NULL ) { task -> mmuState . upar [ 5 ] = mcb -> blockAddr ; task -> mmuState . updr [ 5 ] = PDR_ACC_RW | PDR_SIZ_8K ; task -> mmuState . kpar [ 5 ] = mcb -> blockAddr ; task -> mmuState . kpdr [ 5 ] = PDR_ACC_RW | PDR_SIZ_8K ; endalloc = ( WORD ) 8192 * 6 ; } else { kprintf ( " \n " , task ) ; return ( ENOMEM ) ; } } ptucb = ( PTUCB ) ( endalloc - tucbsize ) ; task -> taskTUCB = ptucb ; mcb = muxx_mem_getblock ( task , 0100 , MMCB_FLG_STK , 6 ) ; if ( mcb != NULL ) { task -> mmuState . upar [ 6 ] = mcb -> blockAddr - 0100 ; task -> mmuState . updr [ 6 ] = PDR_ACC_RW | PDR_SIZ_4K | PDR_DIR_DN ; task -> mmuState . kpar [ 6 ] = mcb -> blockAddr - 0100 ; task -> mmuState . kpdr [ 6 ] = PDR_ACC_RW | PDR_SIZ_4K | PDR_DIR_DN ; } else { return ( ENOMEM ) ; } task -> mmuState . kpar [ 7 ] = 07600 ; task -> mmuState . kpdr [ 7 ] = PDR_ACC_RW | PDR_SIZ_8K ; if ( task -> privileges . prvflags . ioprv || task -> privileges . prvflags . operprv ) { task -> mmuState . upar [ 7 ] = 07600 ; task -> mmuState . updr [ 7 ] = PDR_ACC_RW | PDR_SIZ_8K ; } else if ( task -> privileges . prvflags . auditprv ) { task -> mmuState . upar [ 7 ] = 07600 ; task -> mmuState . updr [ 7 ] = PDR_ACC_RO | PDR_SIZ_8K ; } else { task -> mmuState . upar [ 7 ] = 0 ; task -> mmuState . updr [ 7 ] = PDR_ACC_NA | PDR_SIZ_0K ; } if ( ttype == DRV_TASK ) { mcb = muxx_mem_getblock ( task , DRV_BUFSIZ / 64 , MMCB_FLG_BUF , 5 ) ; if ( mcb != NULL ) { task -> mmuState . upar [ 4 ] = mcb -> blockAddr ; task -> mmuState . updr [ 4 ] = PDR_ACC_RW | PDR_SIZ_1K ; task -> mmuState . kpar [ 4 ] = mcb -> blockAddr ; task -> mmuState . kpdr [ 4 ] = PDR_ACC_RW | PDR_SIZ_1K ; } else { return ( ENOMEM ) ; } } return ( rc ) ; }
Setup the shared memory space for a new task
Setup the shared memory space for a new task
// Extract task size // Extract task size // Check combinations of task type, task size and stack sze // Right now stack size setting // is not supported // System tasks: any size is allowed // User tasks: any size is allowed // Driver tasks: Big (TSZ_BIG) is not allowed /*
  ** Kernel common pages (0-2)
  */ /*
  ** Task private space
  */ // First page, always present (page 3, 8KB) // Second page, present for TSS_MED processes, page 4 8KB // Second page, present for TSS_BIG processes, page 5 8KB /*
  ** Point to TUCB at the end of the allocated space
  ** We can't initialize the TUCB at this point because the
  ** memory for the new task has not been set up.
  ** The TUCB will be prepared by the task initialization code
  ** in crt0.
  **/ /*
  ** Task stack space
  ** The stack size options should be evaluated and applied here
  ** Since the stack grows downward, the PAR contains Addr - Size 
  ** so the physical addresses are properly calculated without
  ** overlapping.
  **
  ** Example: Base virtual address: 0140000
  **          Top of stack:         0157777 (0120000 + 020000 - 1)
  **          Bottom of stack:      0150000 (0120000 + 010000 )
  **          PAR value:            0500
  **          Size:                 0100 (4K)
  **          Physical range:       060000:067777   
  */ /*
  ** IOspace block
  ** 
  ** Map to user mode only if privileged process
  */ /*
  ** Driver task (allocate 1KB at page 5 for buffer space)
  ** DRV_TASK can not be big, so the page 5 should always be free
  **
  */