Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

652 lines
13 KiB

#include "insignia.h"
#include "host_def.h"
/*
* SoftPC Revision 3.0
*
* Title : Global variable definitions
*
* Description : Contains definitions for registers and general
* variables required by all modules.
*
* Author : Henry Nash
*
* Notes : None
*
*/
/*
* static char SccsID[]="@(#)xt.c 1.22 01/23/95 Copyright Insignia Solutions Ltd.";
*/
/*
* O/S include files.
*/
#include <stdio.h>
#include TypesH
/*
* SoftPC include files
*/
#include "xt.h"
#include CpuH
#include "sas.h"
/*
* ============================================================================
* Global data
* ============================================================================
*/
/*
specific CPU variables.
*/
word cpu_interrupt_map; /* Bit map of ints outstanding */
half_word cpu_int_translate[16]; /* this will go very soon! */
/*
*
* The current usage is:
*
* 0 - Hardware interrupt
* 1-7 - Not Used
* 8 - Software Int - set by cpu_sw_interrupt() - REMOVED!
* 9 - Trap
* 10 - Reset IP after a POP/MOV CS.
* 11 - Trap flag changed - this has delay.
* 12-15 - Not Used
*/
word cpu_int_delay; /* Delay before pending interrupt */
int trap_delay_count;
/*
* The lock flag prevents the Interrupt Controller Adapter from being
* called from a signal handler while it is already active in the mainline.
*/
half_word ica_lock;
/*
* The actual CCPU registers
*/
#if defined(CCPU) && !defined(CPU_30_STYLE)
#ifndef MAC_LIKE
reg A; /* Accumulator */
reg B; /* Base */
reg C; /* Count */
reg D; /* Data */
reg BP; /* Base pointer */
reg SI; /* Source Index */
reg DI; /* Destination Index */
#endif /* MAC_LIKE */
reg SP; /* Stack Pointer */
reg IP; /* Instruction Pointer */
reg CS; /* Code Segment */
reg DS; /* Data Segment */
reg SS; /* Stack Segment */
reg ES; /* Extra Segment */
/* Code Segment Register */
half_word CS_AR; /* Access Rights Byte */
sys_addr CS_base; /* Base Address */
word CS_limit; /* Segment 'size' */
int CPL; /* Current Privilege Level */
/* Data Segment Register */
half_word DS_AR; /* Access Rights Byte */
sys_addr DS_base; /* Base Address */
word DS_limit; /* Segment 'size' */
/* Stack Segment Register */
half_word SS_AR; /* Access Rights Byte */
sys_addr SS_base; /* Base Address */
word SS_limit; /* Segment 'size' */
/* Extra Segment Register */
half_word ES_AR; /* Access Rights Byte */
sys_addr ES_base; /* Base Address */
word ES_limit; /* Segment 'size' */
/* Global Descriptor Table Register */
sys_addr GDTR_base; /* Base Address */
word GDTR_limit; /* Segment 'size' */
/* Interrupt Descriptor Table Register */
sys_addr IDTR_base; /* Base Address */
word IDTR_limit; /* Segment 'size' */
/* Local Descriptor Table Register */
reg LDTR; /* Selector */
sys_addr LDTR_base; /* Base Address */
word LDTR_limit; /* Segment 'size' */
/* Task Register */
reg TR; /* Selector */
sys_addr TR_base; /* Base Address */
word TR_limit; /* Segment 'size' */
mreg MSW; /* Machine Status Word */
int STATUS_CF;
int STATUS_SF;
int STATUS_ZF;
int STATUS_AF;
int STATUS_OF;
int STATUS_PF;
int STATUS_TF;
int STATUS_IF;
int STATUS_DF;
int STATUS_NT;
int STATUS_IOPL;
#endif /* defined(CCPU) && !defined(CPU_30_STYLE) */
/*
* Global Flags and variables
*/
int verbose; /* TRUE => trace instructions */
/*
* Misc. Prot Mode support routines which are independant of CPU type
* ---------------------------------
*/
#ifdef CPU_30_STYLE
#ifndef GISP_CPU /* GISP has its own versions of these internal to the CPU */
#define GET_SELECTOR_INDEX_TIMES8(x) ((x) & 0xfff8)
#define GET_SELECTOR_TI(x) (((x) & 0x0004) >> 2)
#if defined(CPU_40_STYLE)
#if defined(PROD) && !defined(CCPU)
#undef effective_addr
GLOBAL LIN_ADDR effective_addr IFN2(IU16, seg, IU32, off)
{
return (*(Cpu.EffectiveAddr))(seg, off);
}
#endif /* PROD & !CCPU */
#else /* !CPU_40_STYLE */
#if !(defined(NTVDM) && defined(MONITOR)) /* MS NT monitor has own effective_addr fn */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Calculate effective address. */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
GLOBAL LIN_ADDR effective_addr IFN2(IU16, seg, IU32, off)
{
LIN_ADDR descr_addr;
DESCR entry;
if ((!getPE()) || getVM()) {
return ((LIN_ADDR)seg << 4) + off;
} else {
#if defined(SWIN_CPU_OPTS) || defined(CPU_40_STYLE)
LIN_ADDR base;
if (Cpu_find_dcache_entry( seg, &base ))
{
/* Cache Hit!! */
return base + off;
}
#endif /* SWIN_CPU_OPTS or CPU_40_STYLE*/
if ( selector_outside_table(seg, &descr_addr) == 1 ) {
/*
* This is probably not a major disaster, just a result
* of the fact that after protected mode is invoked it
* will take say 5-10 instructions for an application
* to update all the segment registers. We just
* maintain real mode semantics while this error occurs.
*/
return ((LIN_ADDR)seg << 4) + off;
}
else
{
read_descriptor(descr_addr, &entry);
return entry.base + off;
}
}
}
#endif /* !(NTVDM & MONITOR) */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Read a decriptor table entry from memory. */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#endif /* !CPU_40_STYLE */
GLOBAL void read_descriptor IFN2(LIN_ADDR, addr, DESCR *, descr)
{
IU32 first_dword, second_dword;
IU32 limit;
/*
* The format of a 286 descriptor is:-
*
* ===========================
* +1 | LIMIT 15-0 | +0
* ===========================
* +3 | BASE 15-0 | +2
* ===========================
* +5 | AR | BASE 23-16 | +4
* ===========================
* +7 | RESERVED | +6
* ===========================
*/
/*
* The format of a 386 descriptor is:-
*
* ============================= AR = Access Rights.
* +1 | LIMIT 15-0 | +0 AVL = Available.
* ============================= D = Default Operand
* +3 | BASE 15-0 | +2 Size, = 0 16-bit
* ============================= = 1 32-bit.
* +5 | AR | BASE 23-16 | +4 G = Granularity,
* ============================= = 0 byte limit
* | | | | |A|LIMIT| = 1 page limit.
* +7 | BASE 31-24 |G|D|0|V|19-16| +6
* | | | | |L| |
* =============================
*
*/
/* read in decriptor with minimum interaction with memory */
#if defined(NTVDM) && defined(CPU_40_STYLE)
/* On NT, this routine can be called from non-CPU threads, so we don't */
/* want to use SAS at all. Instead, we rely on NtGetPtrToLinAddrByte, */
/* which is provided by the CPU and is safe for multi-threading. We are*/
/* also relying on the fact the NT is always little-endian. */
{
IU32 *desc_addr = (IU32 *) NtGetPtrToLinAddrByte(addr);
first_dword = *desc_addr;
second_dword = *(desc_addr + 1);
}
#else
first_dword = sas_dw_at(addr);
second_dword = sas_dw_at(addr+4);
#endif
/* load attributes and access rights */
descr->AR = (second_dword >> 8) & 0xff;
/* unpack the base */
descr->base = (first_dword >> 16) |
#ifdef SPC386
(second_dword & 0xff000000) |
#endif
(second_dword << 16 & 0xff0000 );
/* unpack the limit */
#ifndef SPC386
descr->limit = first_dword & 0xffff;
#else
limit = (first_dword & 0xffff) | (second_dword & 0x000f0000);
if ( second_dword & 0x00800000 ) /* check bit 23 */
{
/* Granularity Bit Set. Limit is expressed in pages
(4k bytes), convert to byte limit */
limit = limit << 12 | 0xfff;
}
descr->limit = limit;
#endif /* ifndef SPC386 else */
}
#if !(defined(NTVDM) && defined(MONITOR)) /* MS NT monitor has own selector_outside_table fn */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Check if selector outside bounds of GDT or LDT */
/* Return 1 for outside table, 0 for inside table. */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
GLOBAL boolean selector_outside_table IFN2(IU16, selector, LIN_ADDR *, descr_addr)
{
/* selector (I) selector to be checked */
/* descr_addr (O) address of related descriptor */
LIN_ADDR offset;
offset = GET_SELECTOR_INDEX_TIMES8(selector);
/* choose a table */
if ( GET_SELECTOR_TI(selector) == 0 )
{
/* GDT - trap NULL selector or outside table */
if ( offset == 0 || offset + 7 > getGDT_LIMIT() )
return 1;
*descr_addr = getGDT_BASE() + offset;
}
else
{
/* LDT - trap invalid LDT or outside table */
if ( getLDT_SELECTOR() == 0 || offset + 7 > getLDT_LIMIT() )
return 1;
*descr_addr = getLDT_BASE() + offset;
}
return 0;
}
#endif /* !(NTVDM & MONITOR) */
#endif /* !GISP_CPU */
#endif /* CPU_30_STYLE */
/*
* The following is a table lookup for finding parity of a byte
*/
#if !defined(MAC_LIKE) && !defined(CPU_30_STYLE)
half_word pf_table[] = {
1, /* 00 */
0, /* 01 */
0, /* 02 */
1, /* 03 */
0, /* 04 */
1, /* 05 */
1, /* 06 */
0, /* 07 */
0, /* 08 */
1, /* 09 */
1, /* 0a */
0, /* 0b */
1, /* 0c */
0, /* 0d */
0, /* 0e */
1, /* 0f */
0, /* 10 */
1, /* 11 */
1, /* 12 */
0, /* 13 */
1, /* 14 */
0, /* 15 */
0, /* 16 */
1, /* 17 */
1, /* 18 */
0, /* 19 */
0, /* 1a */
1, /* 1b */
0, /* 1c */
1, /* 1d */
1, /* 1e */
0, /* 1f */
0, /* 20 */
1, /* 21 */
1, /* 22 */
0, /* 23 */
1, /* 24 */
0, /* 25 */
0, /* 26 */
1, /* 27 */
1, /* 28 */
0, /* 29 */
0, /* 2a */
1, /* 2b */
0, /* 2c */
1, /* 2d */
1, /* 2e */
0, /* 2f */
1, /* 30 */
0, /* 31 */
0, /* 32 */
1, /* 33 */
0, /* 34 */
1, /* 35 */
1, /* 36 */
0, /* 37 */
0, /* 38 */
1, /* 39 */
1, /* 3a */
0, /* 3b */
1, /* 3c */
0, /* 3d */
0, /* 3e */
1, /* 3f */
0, /* 40 */
1, /* 41 */
1, /* 42 */
0, /* 43 */
1, /* 44 */
0, /* 45 */
0, /* 46 */
1, /* 47 */
1, /* 48 */
0, /* 49 */
0, /* 4a */
1, /* 4b */
0, /* 4c */
1, /* 4d */
1, /* 4e */
0, /* 4f */
1, /* 50 */
0, /* 51 */
0, /* 52 */
1, /* 53 */
0, /* 54 */
1, /* 55 */
1, /* 56 */
0, /* 57 */
0, /* 58 */
1, /* 59 */
1, /* 5a */
0, /* 5b */
1, /* 5c */
0, /* 5d */
0, /* 5e */
1, /* 5f */
1, /* 60 */
0, /* 61 */
0, /* 62 */
1, /* 63 */
0, /* 64 */
1, /* 65 */
1, /* 66 */
0, /* 67 */
0, /* 68 */
1, /* 69 */
1, /* 6a */
0, /* 6b */
1, /* 6c */
0, /* 6d */
0, /* 6e */
1, /* 6f */
0, /* 70 */
1, /* 71 */
1, /* 72 */
0, /* 73 */
1, /* 74 */
0, /* 75 */
0, /* 76 */
1, /* 77 */
1, /* 78 */
0, /* 79 */
0, /* 7a */
1, /* 7b */
0, /* 7c */
1, /* 7d */
1, /* 7e */
0, /* 7f */
0, /* 80 */
1, /* 81 */
1, /* 82 */
0, /* 83 */
1, /* 84 */
0, /* 85 */
0, /* 86 */
1, /* 87 */
1, /* 88 */
0, /* 89 */
0, /* 8a */
1, /* 8b */
0, /* 8c */
1, /* 8d */
1, /* 8e */
0, /* 8f */
1, /* 90 */
0, /* 91 */
0, /* 92 */
1, /* 93 */
0, /* 94 */
1, /* 95 */
1, /* 96 */
0, /* 97 */
0, /* 98 */
1, /* 99 */
1, /* 9a */
0, /* 9b */
1, /* 9c */
0, /* 9d */
0, /* 9e */
1, /* 9f */
1, /* a0 */
0, /* a1 */
0, /* a2 */
1, /* a3 */
0, /* a4 */
1, /* a5 */
1, /* a6 */
0, /* a7 */
0, /* a8 */
1, /* a9 */
1, /* aa */
0, /* ab */
1, /* ac */
0, /* ad */
0, /* ae */
1, /* af */
0, /* b0 */
1, /* b1 */
1, /* b2 */
0, /* b3 */
1, /* b4 */
0, /* b5 */
0, /* b6 */
1, /* b7 */
1, /* b8 */
0, /* b9 */
0, /* ba */
1, /* bb */
0, /* bc */
1, /* bd */
1, /* be */
0, /* bf */
1, /* c0 */
0, /* c1 */
0, /* c2 */
1, /* c3 */
0, /* c4 */
1, /* c5 */
1, /* c6 */
0, /* c7 */
0, /* c8 */
1, /* c9 */
1, /* ca */
0, /* cb */
1, /* cc */
0, /* cd */
0, /* ce */
1, /* cf */
0, /* d0 */
1, /* d1 */
1, /* d2 */
0, /* d3 */
1, /* d4 */
0, /* d5 */
0, /* d6 */
1, /* d7 */
1, /* d8 */
0, /* d9 */
0, /* da */
1, /* db */
0, /* dc */
1, /* dd */
1, /* de */
0, /* df */
0, /* e0 */
1, /* e1 */
1, /* e2 */
0, /* e3 */
1, /* e4 */
0, /* e5 */
0, /* e6 */
1, /* e7 */
1, /* e8 */
0, /* e9 */
0, /* ea */
1, /* eb */
0, /* ec */
1, /* ed */
1, /* ee */
0, /* ef */
1, /* f0 */
0, /* f1 */
0, /* f2 */
1, /* f3 */
0, /* f4 */
1, /* f5 */
1, /* f6 */
0, /* f7 */
0, /* f8 */
1, /* f9 */
1, /* fa */
0, /* fb */
1, /* fc */
0, /* fd */
0, /* fe */
1 /* ff */
};
#endif /* !defined(MAC_LIKE) && !defined(CPU_30_STYLE) */
/*(
*========================== CsIsBig ===================================
* CsIsBig
*
* Purpose
* This function returns true if the indicated code segment is a 32 bit
* one, and false if it isn't.
*
* Input
* csVal The selector to check
*
* Outputs
* None.
*
* Description
* Look at the descriptor.
)*/
GLOBAL IBOOL
CsIsBig IFN1(IU16, csVal)
{
#ifdef SPC386
LIN_ADDR base, offset; /* Of the descriptor to use */
if(getVM() || !getPE()) {
return(FALSE); /* no 32 bit CS in V86 or real modes */
} else {
offset = csVal & (~7); /* remove the RPL and TI gives offset */
if (csVal & 4) { /* check TI bit */
base = getLDT_BASE();
} else {
base = getGDT_BASE();
}
/*
* Return true if the big bit in the descriptor is set.
*/
return(sas_hw_at(base + offset + 6) & 0x40);
}
#else /* SPC386 */
return (FALSE);
#endif /* SPC386 */
}