|
|
1.1 ! root 1: /* ! 2: * fakeff.c ! 3: * Simulate all the calls for far memory access from COH 286. ! 4: * Far pointers are simulated with virtual addresses. ! 5: */ ! 6: #include <sys/coherent.h> ! 7: #include <sys/seg.h> ! 8: #include <sys/fakeff.h> ! 9: ! 10: extern SR allocp; ! 11: ! 12: /* ! 13: * Initialize a virtual address to access physical memory at location ! 14: * 'paddr', of size 'len' bytes. It provides read and write (but not ! 15: * execute) access. When no longer required, a virtual address should be ! 16: * released by vrelse. ! 17: */ ! 18: faddr_t ! 19: map_pv(paddr, len) ! 20: __paddr_t paddr; ! 21: fsize_t len; ! 22: { ! 23: int s; /* Return value of sphi(). */ ! 24: int npage; /* Number of pages we must allocate. */ ! 25: faddr_t chunk_start; /* Start of allocated segment in vmem. */ ! 26: faddr_t retval; /* Address of desired physical memory in vmem. */ ! 27: int base1; /* Offset into ptable1_v[]. */ ! 28: cseg_t pte; /* Build page table entries here. */ ! 29: ! 30: /* Figure out how many clicks we need to map. ! 31: * [ ] What we want. ! 32: * [ | | ] What we get. ! 33: * Total number of clicks is: ! 34: * (click up from (paddr+len)) - (click down from paddr) ! 35: */ ! 36: ! 37: npage = btoc(paddr+len) - btocrd(paddr); ! 38: ! 39: /* Note that sysmem.vaddre is ALWAYS click aligned. */ ! 40: ! 41: /* ! 42: * Allocate the required chunk of virtual memory space. ! 43: * This could be a lot more sophisticated. For expedience, ! 44: * there is no way to free this after it has been allocated, ! 45: * and there are no checks to see if we ran out of virtual space. ! 46: */ ! 47: s = sphi(); ! 48: chunk_start = sysmem.vaddre; ! 49: sysmem.vaddre += ctob(npage); ! 50: spl(s); ! 51: ! 52: /* ! 53: * Figure out where the desired physical address ends up in vmem. ! 54: */ ! 55: retval = chunk_start + (paddr - ctob(btoc(paddr))); ! 56: ! 57: /* ! 58: * Load the page table. ! 59: */ ! 60: base1 = btocrd(chunk_start); ! 61: pte = ctob(btocrd(paddr)); ! 62: do { ! 63: ptable1_v[base1] = pte | SEG_SRW; ! 64: base1++; ! 65: pte += ctob(1); /* Bump up to next physical click. */ ! 66: } while (--npage > 0); ! 67: mmuupd(); /* Tell the mmu about the new map. */ ! 68: ! 69: return(retval); ! 70: } /* map_pv() */ ! 71: ! 72: /* ! 73: * Release a virtual address that we previously obtained with function ! 74: * map_pv(). ! 75: */ ! 76: void ! 77: unmap_pv(faddr) ! 78: faddr_t faddr; ! 79: { ! 80: /* For the moment, this function does nothing. */ ! 81: } ! 82: ! 83: /* ! 84: * Translate virtual address to physical address. ! 85: * Returns the current physical address associated with virtual address 'vaddr'. ! 86: * Returns 0 if that portion of virtual address space is not associated with ! 87: * any physical memory. ! 88: */ ! 89: paddr_t ! 90: vtop(vaddr) ! 91: caddr_t vaddr; ! 92: { ! 93: paddr_t retval; ! 94: unsigned int ptable_idx; /* Index into ptable1_v[]. */ ! 95: ! 96: ptable_idx = btocrd(vaddr); ! 97: ! 98: /* ! 99: * There is a 4Mbyte virtual page table ptable1_v[] which is ! 100: * all the bottom level page tables appended into a big array. ! 101: * Note that there are huge holes in this data structure, for ! 102: * unmapped virtual address space. ! 103: * ! 104: * We are going to look up 'vaddr' in the virtual page table ! 105: * ptable1_v[]. ! 106: * ! 107: * But first, we have to see if the portion of page table we are ! 108: * going to look at exists. We do this by looking at the one click ! 109: * long page table that maps the virtual page table, PPTABLE1_V[]. ! 110: */ ! 111: retval = 0; /* Assume entry not found. */ ! 112: ! 113: if (ptable0_v[btosrd(vaddr)] & SEG_SRO) { ! 114: /* ! 115: * ASSERTION: The portion of ptable1_v[] we want is valid. ! 116: */ ! 117: if (ptable1_v[ptable_idx] & SEG_SRO) { ! 118: ! 119: /* ! 120: * ASSERTION: 'vaddr' corresponds to some ! 121: * physical memory. ! 122: * ! 123: * Note that the address of a physical click is ! 124: * all above bit 11 in the PTE. ! 125: */ ! 126: retval = (ptable1_v[ptable_idx] & ~(NBPC - 1)); ! 127: retval += ((long) vaddr & (NBPC - 1)); ! 128: } ! 129: } ! 130: ! 131: T_PIGGY( 0x10, printf("vtop(%x)=%x, ", vaddr, retval); ); ! 132: ! 133: return(retval); ! 134: } /* vtop() */ ! 135: ! 136: /* ! 137: * Translate system global address 'vpaddr' to physical address. ! 138: * ! 139: * May cause a panic if 'vpaddr' does not correspond to a real physical ! 140: * address. ! 141: */ ! 142: paddr_t ! 143: vptop(vpaddr) ! 144: paddr_t vpaddr; ! 145: { ! 146: paddr_t retval; ! 147: cseg_t pte; /* Page table entry from sysmem.u.pbase[]. */ ! 148: ! 149: T_PIGGY( 0x10, printf("vptop(%x)=", vpaddr); ); ! 150: ! 151: pte = sysmem.u.pbase[btocrd(vpaddr)]; ! 152: pte &= ~(NBPC - 1); /* Strip off the non-address information. */ ! 153: ! 154: retval = pte | (vpaddr & (NBPC - 1)); ! 155: ! 156: T_PIGGY( 0x10, printf("%x,", retval); ); ! 157: ! 158: return(retval); ! 159: } /* vptop() */ ! 160: ! 161: /* ! 162: * Convert from virtual address to system global address. Similar to MAPIO(), ! 163: * but does not require separate segment and offset. ! 164: * ! 165: * Only works for Kernel Space virtual addresses. ! 166: */ ! 167: paddr_t ! 168: vtovp(vaddr) ! 169: caddr_t vaddr; ! 170: { ! 171: paddr_t retval; ! 172: ! 173: T_PIGGY( 0x10, printf("vtopvp(%x)=", vaddr); ); ! 174: ! 175: retval = MAPIO((allocp.sr_segp->s_vmem), (vaddr - allocp.sr_base)); ! 176: ! 177: T_PIGGY( 0x10, printf("%x, ", retval); ); ! 178: ! 179: return( retval ); ! 180: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.