NT4/private/ntos/nthals/halflex/alpha/minitlb.c
2020-09-30 17:12:29 +02:00

222 lines
5.8 KiB
C

/*++
Copyright (c) 1995 DeskStation Technology
Module Name:
minitlb.c
Abstract:
This module contains the support functions for the TLB that allows
access to the sparse address spaces.
Author:
Michael D. Kinney 8-Aug-1995
Environment:
Kernel mode
Revision History:
--*/
#include "halp.h"
#define MINI_TLB_ATTRIBUTES_HIGH 0xfffffc03
#define MINI_TLB_ATTRIBUTES_LOW 0xc0000004
#define MINI_TLB_ENTRY_HIGH 0xfffffc03
UCHAR HalpMiniTlbAttributesLookupTable[16] = {
0, // ISA I/O Space 0x00000000 - 0x01ffffff
0, // ISA Memory Space 0x00000000 - 0x01ffffff
1, // PCI I/O Space 0x00000000 - 0x01ffffff
1, // PCI Memory Space 0x00000000 - 0x01ffffff
1, // PCI High Memory Space 0x40000000 - 0x41ffffff
1, // PCI High Memory Space 0x42000000 - 0x43ffffff
1, // PCI High Memory Space 0x44000000 - 0x45ffffff
1, // PCI High Memory Space 0x46000000 - 0x47ffffff
3, // PCI Config Type 0 Space Devices 0-13 0x00000000 - 0x01ffffff
3, // PCI Config Type 0 Space Device 14 0x02000000 - 0x03ffffff
3, // PCI Config Type 0 Space Device 15 0x04000000 - 0x05ffffff
3, // PCI Config Type 0 Space Device 16 0x08000000 - 0x09ffffff
3, // PCI Config Type 0 Space Device 17 0x10000000 - 0x11ffffff
3, // PCI Config Type 0 Space Device 18 0x20000000 - 0x21ffffff
3, // PCI Config Type 0 Space Device 19 0x40000000 - 0x41ffffff
3 // PCI Config Type 1 Space 0x00000000 - 0x01ffffff
};
UCHAR HalpMiniTlbEntryLookupTable[16] = {
0x80, // ISA I/O Space 0x00000000 - 0x01ffffff
0x00, // ISA Memory Space 0x00000000 - 0x01ffffff
0x80, // PCI I/O Space 0x00000000 - 0x01ffffff
0x00, // PCI Memory Space 0x00000000 - 0x01ffffff
0x20, // PCI High Memory Space 0x40000000 - 0x41ffffff
0x21, // PCI High Memory Space 0x42000000 - 0x43ffffff
0x22, // PCI High Memory Space 0x44000000 - 0x45ffffff
0x23, // PCI High Memory Space 0x46000000 - 0x47ffffff
0x00, // PCI Config Type 0 Space Devices 0-13 0x00000000 - 0x01ffffff
0x01, // PCI Config Type 0 Space Device 14 0x02000000 - 0x03ffffff
0x02, // PCI Config Type 0 Space Device 15 0x04000000 - 0x05ffffff
0x04, // PCI Config Type 0 Space Device 16 0x08000000 - 0x09ffffff
0x08, // PCI Config Type 0 Space Device 17 0x10000000 - 0x11ffffff
0x10, // PCI Config Type 0 Space Device 18 0x20000000 - 0x21ffffff
0x20, // PCI Config Type 0 Space Device 19 0x40000000 - 0x41ffffff
0x80 // PCI Config Type 1 Space 0x00000000 - 0x01ffffff
};
ULONG HalpMiniTlbEntryAddressLow[4] = {
0x1000000c, // Mini TLB Entry 0
0x5000000c, // Mini TLB Entry 1
0x9000000c, // Mini TLB Entry 2
0xd000000c // Mini TLB Entry 3
};
UCHAR HalpMiniTlbAttributes = 0x00;
UCHAR HalpMiniTlbEntry[4] = {0x00,0x00,0x00,0x00};
UCHAR HalpMiniTlbTag[4] = {0xff, 0xff, 0xff, 0xff};
ULONG HalpMiniTlbIndex = 0;
ULONG HalpMiniTlbEntries = 4;
VOID
HalpMiniTlbProgramEntry(
ULONG Index
)
{
HalpMiniTlbAttributes &= (~(0x03 << (Index * 2)));
HalpMiniTlbAttributes |= (HalpMiniTlbAttributesLookupTable[HalpMiniTlbTag[Index]] << (Index * 2));
HalpMiniTlbEntry[Index] = HalpMiniTlbEntryLookupTable[HalpMiniTlbTag[Index]];
HalpWriteAbsoluteUlong(MINI_TLB_ATTRIBUTES_HIGH,MINI_TLB_ATTRIBUTES_LOW,((ULONG)HalpMiniTlbAttributes)<<8);
HalpWriteAbsoluteUlong(MINI_TLB_ENTRY_HIGH,HalpMiniTlbEntryAddressLow[Index],((ULONG)HalpMiniTlbEntry[Index])<<8);
}
VOID
HalpMiniTlbSaveState(
VOID
)
{
}
VOID
HalpMiniTlbRestoreState(
VOID
)
{
ULONG i;
for(i=0;i<4;i++) {
if (HalpMiniTlbTag[i]!=0xff) {
HalpMiniTlbProgramEntry(i);
}
}
}
ULONG
HalpMiniTlbMatch(
PVOID Qva,
ULONG StartIndex
)
{
ULONG Tag;
ULONG i;
Tag = ((ULONG)(Qva) >> 25) & 0x0f;
for(i=StartIndex;i<4 && HalpMiniTlbTag[i]!=Tag;i++);
return(i);
}
ULONG
HalpMiniTlbAllocateEntry(
PVOID Qva,
PPHYSICAL_ADDRESS TranslatedAddress
)
{
ULONG Index;
//
// Check for a tag match among the fixed TLB entries.
//
Index = HalpMiniTlbMatch(Qva,HalpMiniTlbEntries);
if (Index==4) {
//
// There was no match, so check for an available TLB entry.
//
if (HalpMiniTlbEntries<=1) {
//
// No TLB entries were available. Return NULL
//
return(FALSE);
}
//
// A TLB entry was available. Fill it in.
//
HalpMiniTlbEntries--;
Index = HalpMiniTlbEntries;
HalpMiniTlbTag[Index] = (UCHAR)(((ULONG)(Qva) >> 25) & 0x0f);
HalpMiniTlbProgramEntry(Index);
//
// Reset the random replacement index
//
HalpMiniTlbIndex = 0;
}
TranslatedAddress->QuadPart = ROGUE_TRANSLATED_BASE_PHYSICAL;
TranslatedAddress->QuadPart += (Index << 30) | (((ULONG)(Qva) & 0x01ffffff) << IO_BIT_SHIFT);
return(TRUE);
}
PVOID
HalpMiniTlbResolve(
PVOID Qva
)
{
ULONG Index;
//
// Check for a tag match among all the TLB entries
//
Index = HalpMiniTlbMatch(Qva,0);
if (Index==4) {
//
// There was no match, so replace one of the TLB entries
//
Index = HalpMiniTlbIndex;
HalpMiniTlbTag[Index] = (UCHAR)(((ULONG)(Qva) >> 25) & 0x0f);
HalpMiniTlbProgramEntry(Index);
//
// Point random replacement index at next available entry.
//
HalpMiniTlbIndex++;
if (HalpMiniTlbIndex >= HalpMiniTlbEntries) {
HalpMiniTlbIndex = 0;
}
}
return( (PVOID)(DTI_QVA_ENABLE | ((0x08 | Index) << 25) | ((ULONG)(Qva) & 0x01ffffff)) );
}