summaryrefslogtreecommitdiff
path: root/cpu/amd/geode_lx/gplvsa_ii/inc/vsa2.h
blob: 79299d4e0f3b8105563eb87394a6f15cd7079a33 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
/*
* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.

* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307 USA 
*/

#define VSM_SIGNATURE		0x204D5356	// 'VSM '
#define VSA_VERSION		0x03B0		// SysMgr Version


#define BYTE_IO                0x01
#define WORD_IO                0x03
#define DWORD_IO               0x0F
#define IO_WRITE               0x80



typedef  unsigned char UCHAR;
typedef  unsigned long ULONG;
typedef  unsigned short USHORT;



#define HIWORD(p)  ((USHORT) ((p) >> 16))

typedef struct {
	unsigned short Alignment: 5;		// 2^(n+5)  (e.g. 00000 = 32-byte boundary)
	unsigned short LoadHi: 1;			// 1 = must load VSM above top of memory
	unsigned short LoadLo: 1;			// 1 = must load VSM below 1 MB
	unsigned short SkipMe: 1;			// 1 = Skip this VSM
	unsigned short Reserved: 8;
} Requirements;






//*********************************************************************
// 			Structures
//*********************************************************************

typedef struct {
  union {
    ULONG  Reg_EAX;
    USHORT Reg_AX;
	struct {
	  UCHAR Reg_AL;
	  UCHAR Reg_AH;
	};
  };
  union {
    ULONG  Reg_EBX;
    USHORT Reg_BX;
	struct {
	  UCHAR Reg_BL;
	  UCHAR Reg_BH;
	};
  };
  union {
    ULONG  Reg_ECX;
    USHORT Reg_CX;
	struct {
	  UCHAR Reg_CL;
	  UCHAR Reg_CH;
	};
  };
  union {
    ULONG  Reg_EDX;
    USHORT Reg_DX;
	struct {
	  UCHAR Reg_DL;
	  UCHAR Reg_DH;
	};
  };
  union {
    ULONG  Reg_EBP;
    USHORT Reg_BP;
  };
  union {
    ULONG  Reg_ESI;
    USHORT Reg_SI;
  };
  union {
    ULONG  Reg_EDI;
    USHORT Reg_DI;
  };
  USHORT Reg_DS;
  USHORT Reg_ES;
  USHORT Flags;
  UCHAR PIC0_Mask;
  UCHAR PIC1_Mask;			
} INT_REGS;



typedef struct {			// Used by SVDC & RSDC instructions
	USHORT	limit_15_0;
	USHORT	base_15_0;
	UCHAR	base_23_16;
	UCHAR	attr;
#define G_BIT				0x80
#define D_BIT				0x40

	UCHAR	limit_19_16;
	UCHAR	base_31_24;
	USHORT	selector;
} Descriptor;


typedef struct {
	ULONG	Reserved;
	ULONG	SMM_CTL_MSR;
	ULONG	write_data;
	USHORT	IO_addr;
	USHORT	data_size;
    union {
  	  struct {
	    USHORT CS_Writable: 1;
	    USHORT IO_Write:    1;
	    USHORT REP_Prefix:  1;
	    USHORT SMINT:       1;

	    USHORT HALT:        1;
	    USHORT Ext_IO_Trap: 1;
	    USHORT External:    1;
	    USHORT IO_Trap:     1;

	    USHORT Nested:      1;
	    USHORT Reserved:    6;
	    USHORT CS_Readable: 1;
	  } SMI_Flags;
	  USHORT SMI_Flags_Ushort;
	};
  
	USHORT SS_Flags;

    struct {
      ULONG limit;
      ULONG	 base;
      USHORT selector;
      USHORT attr;
	} _CS;

    union {
      USHORT Next_IP;
	  ULONG	Next_EIP;
    };
    union {
      USHORT Current_IP;
	  ULONG	Current_EIP;
    };
	ULONG	r_CR0;
	ULONG	EFLAGS;
	ULONG	r_DR7;
} SmiHeader;






typedef USHORT MSG;
typedef USHORT PRIORITY;
typedef USHORT EVENT;
typedef ULONG  VSM;





#define MAX_MSG_PARAM       4	// Parameter count
#define MAX_MSG_CNT	 	10 	// # entries in message queue

typedef struct {
   MSG Msg;				// Message code
   PRIORITY Priority;			// Priority
   ULONG From_VSM;				// VSM that sent the message
   ULONG Param[MAX_MSG_PARAM];	// Parameters
   ULONG Timestamp;			// Timestamp when message was entered
} Message;


typedef struct {

  // VSM's state
  SmiHeader State;				// SMM header for this VSM

  // NOTE: Flink field must be immediately after State structure
  ULONG Flink;				// Forward link to next VSM
  ULONG Blink;	 			// Backward link to previous VSM
  ULONG SavedESP;				// VSM's stack pointer
  ULONG SysMgr_Ptr;			// Ptr to SysMgr's InfoStuff structure
  ULONG Southbridge;			// PCI address of Southbridge


  // Statistics
  ULONG Adjustment;			// Clocks used by SMM entry/exit
  ULONG Clocks[2];				// Total clocks used by this VSM
  ULONG NumSMIs[2];			// Total SMI count for this VSM
  ULONG FrozenClocks[2]; 		// Copied from Clocks[]
  ULONG FrozenNumSMIs[2];		// Copied from NumSMIs[]
  ULONG StartTime[2];			// Timestamp @ start of timeslice
  ULONG StartClocks[2];		// Timestamp of last INFO /S

  // Floating Point
  UCHAR FPU_State[108];   		// Saved FPU state
  UCHAR FPU_Flag;              // Non-zero if FPU in use

  UCHAR RunFlag;				// VSM's scheduler state

  USHORT ResumeVector;			// Used by SaveToRAM
  USHORT Pad[5];

  // Message Queue
  USHORT EndMsgQ;	 	 		// Offset of *end* of message queue
  USHORT Qhead;				// Message queue head offset
  USHORT Qtail; 				// Message queue tail offset

  // MsgQueue is variable length, so it must be the last field
  Message MsgQueue[MAX_MSG_CNT];	// The VSM's message queue

} System;



//*********************************************************************
// 			VSM Header
//*********************************************************************

typedef struct  {
	ULONG  Signature;			// 'VSM '
	UCHAR  VSM_Type;   			// Type of VSM
	UCHAR  ForCPU;				// Required CPU  (FFFFh for any)
	USHORT ForChipset;			// Required companion I/O  (FFFFh for any)
	USHORT VSM_Version;			// Version of VSM
	ULONG  VSM_Length; 			// Length of VSM module in bytes
	USHORT EntryPoint;	 		// Offset of entry point
	ULONG  DS_Limit;
	Requirements Flag;			// Special requirements/capabilities
	USHORT VSA_Version;
	Descriptor _SS;				// SS: descriptor for this VSM
	Descriptor _DS;			 	// DS: descriptor for this VSM
	Descriptor _ES;				// ES: descriptor for this VSM
	USHORT AlignSystem;			// SysStuff must be DWORD aligned
	System SysStuff;			// Reserved for use by System Manager

} VSM_Header;






//*********************************************************************
// 			VSM Types
//*********************************************************************
#define VSM_SYS_MGR        0x00		// System Manager
#define VSM_AUDIO          0x01		// Xpress Audio
#define VSM_VGA            0x02		// SoftVGA
#define VSM_LEGACY         0x03		// Standard AT peripherals
#define VSM_PM             0x04		// Legacy Power Management
#define VSM_OHCI           0x05		// OHCI
#define VSM_i8042          0x06		// 8042 emulator
#define VSM_DEBUGGER       0x07		// SMI based debugger
#define VSM_ACPI           0x08		// Virtual ACPI
#define VSM_APM            0x09		// APM 1.2
#define VSM_OEM_ACPI       0x0A		// OEM ACPI customizations
#define VSM_SMB            0x0B		// System Management Bus
#define VSM_BATTERY        0x0C		// Battery controller
#define VSM_RTC            0x0D		// Virtual RTC
#define VSM_S2D            0x0E		// SaveToDisk
#define VSM_EXT_AMP        0x0F		// External audio amplifier
#define VSM_PCMCIA         0x10		// PCMCIA
#define VSM_SPY            0x11		// Spy. Receives ALL messages first.
#define VSM_NETWORK        0x12		// Network
#define VSM_GPIO           0x13		// GPIO handler
#define VSM_KEYBOARD       0x14		// USB keyboard to PC/AT emulation
#define VSM_MOUSE          0x15		// USB mouse to PS/2 emulation
#define VSM_USB            0x16		// Universal Serial Bus
#define VSM_FLASH          0x17		// FLASH
#define VSM_INFRARED       0x18		// Infrared
#define VSM_THERMAL        0x19		// Thermal monitor
#define VSM_NULL           0x1A		// Unspecified
#define VSM_MPEG           0x1B		// MPEG video decoder (EMMA)
#define VSM_VIP            0x1C		// Video processor (VIDEC)
#define VSM_LPC            0x1D		// Low Pin Count bus
#define VSM_VUART          0x1E		// Virtual UART
#define VSM_MICRO          0x1F		// MicroController
#define VSM_USER1          0x20		// USER 1
#define VSM_USER2          0x21		// USER 2
#define VSM_USER3          0x22		// USER 3
#define VSM_SYSINFO        0x23		// System Information
#define VSM_SUPERIO        0x24		// PM for SuperIO
#define VSM_EHCI           0x25		// EHCI
#define VSM_MAX_TYPE       VSM_EHCI	// Highest valid VSM type

#define VSM_ANY            0xFF		// Wildcard for SYS_BROADCAST
#define VSM_NOT_SELF       0x4000	// Flag used by SYS_BROADCAST
#define VSM_ALL_EXCEPT     0x8000	// Flag used by SYS_BROADCAST


//*********************************************************************
// SMINT codes used by non-VSA components (BIOS, INIT, etc.)
//*********************************************************************
#define SYS_BIOS_INIT          0x00F0   // VSA installation	from POST
#define SYS_DOS_INSTALL        0x00F2   // VSA installation from DOS prompt
#define SYS_VSM_INSTALL        0x00F3   // Install VSM dynamically
#define SYS_REMOVE             0x00F4   // Unregister events belonging to VSM
#define SYS_INT_RETURN         0x00F5   // Return from call to INT vector
#define SYS_RESUME_FROM_RAM    0x6789   // Resume from RAM
#define SYS_END_OF_POST        0x5000   // Issued by GeodeROM at end of POST
#define SYS_INT13_SMI          0x5001   // Issued by Int 13 module (USB floppy)
#define SYS_INT13CDR_SMI       0x5003   // Issued by Int 13 module (USB CD-ROM)
#define SYS_USB_DEVICE_SMI     0x7777   // Issued by USBBOOT.ROM to access device table

//*********************************************************************
//			Event Priorities
//*********************************************************************
#define NORMAL_PRIORITY        0x0000
#define MAX_PRIORITY           0x7FFF
#define BROADCAST_PRIORITY     0x9000
#define UNREGISTER_PRIORITY    0xFFF0

//*********************************************************************
//			Messages
//*********************************************************************

#define MSG_INITIALIZE		   0		// Perform VSM initialization
  #define EARLY_INIT           0
  #define END_OF_POST_INIT     1

#define MSG_SHUTDOWN           1		// Prepare for system shutdown (cold boot)
#define MSG_SAVE_STATE         2		// Save entire state of device(s) controlled by VSM
#define MSG_RESTORE_STATE      3		// Restore saved state of device(s) controlled by VSM
#define MSG_SET_POWER_STATE    4		// Set device(s) to specified power state
#define MSG_EVENT              5		// A registered  event has occurred
#define MSG_QUEUE_OVERFLOW     6		// The message queue is full.
#define MSG_WARM_BOOT          7		// Prepare for a warm boot
#define MSG_SET_POWER_MODE     9		// Restore saved state of device(s) controlled by VSM
#define MSG_ABORT_POWER_STATE  10		// Power state is to be aborted

//*********************************************************************
//			Events
//*********************************************************************

#define EVENT_GRAPHICS         1		// Video event
#define EVENT_AUDIO            2		// Audio event
#define EVENT_USB              3		// USB event
#define EVENT_ACPI             4		// ACPI register access
#define EVENT_ACPI_TIMER       5		// The ACPI timer expired
#define EVENT_IO_TRAP          6		// I/O trap
#define EVENT_IO_TIMEOUT       7		// I/O timeout
#define EVENT_PME              8		// Power Management
#define EVENT_KEL              9		// KEL
#define EVENT_VIDEO_INACTIVITY 0x0A	// Not supported in GX2
#define EVENT_GPIO             0x0B	// GPIO transition
  #define FALLING_EDGE          (1 << 0)
  #define RISING_EDGE           (1 << 1)
  #define BOTH_EDGES            (FALLING_EDGE | RISING_EDGE) 
  #define PME                   (1 << 2)
  #define DEBOUNCE              (1 << 3)
  #define PULLDOWN              (1 << 4)
  #define PULLUP                (1 << 5)
  #define INVERT                (1 << 6)
  #define OUTPUT                (1 << 7)
  #define OPEN_DRAIN            (1 << 8)
  // INPUT may be removed as if it is not OUTPUT it is assumed to be INPUT
  // this will have almost no impact on the code
  // Do Not use INPUT
  #define INPUT                 (1 << 9) 
  #define AUX1                  (1 << 10)
  #define AUX2                  (1 << 11)
  #define NO_ASMI               (1 << 12)
  #define PM1                   (1 << 13)
  #define GPE                   (1 << 14)
  #define NO_ENABLE             (1L << 15) // do not enable in GPE0_EN or PM1_EN
                                          // when using EVENT_PME
#define EVENT_SOFTWARE_SMI      0x0C	// Software SMI
#define EVENT_PCI_TRAP          0x0D	// PCI trap
#define EVENT_VIRTUAL_REGISTER  0x0E	// Virtual register access
#define EVENT_NMI               0x0F	// NMI
#define EVENT_TIMER             0x10	// Millisecond timer
#define EVENT_DEVICE_TIMEOUT    0x11	// Device timeout
#define EVENT_SEMAPHORE         0x12	// ACPI global lock
#define EVENT_VBLANK            0x13    // Vertical blank
#define EVENT_A20               0x14	// A20 mask toggled
#define EVENT_SMB               0x15	// SMB Controller
#define EVENT_RTC               0x16	// RTC Alarm
#define EVENT_THERMAL           0x17    // THRM pin
#define EVENT_LPC               0x18    // Low Pin Count bus
#define EVENT_UART              0x19
#define EVENT_BLOCKIO           0x1A
#define EVENT_PWM               0x1B
#define MAX_EVENT               EVENT_PWM

// Flags for event registration
#define WRITES_ONLY            (1L << 16)
#define READS_ONLY             (1L << 17)
#define GLIU_ID                (1L << 19)
#define NOT_GLIU0              (1L << 20)
#define NOT_GLIU1              (1L << 21)
#define NOT_GLIU2              (1L << 22)
#define ALL_GLIUS              (NOT_GLIU0 | NOT_GLIU1 | NOT_GLIU2)
// Flags used for EVENT_TIMER must be >= bit 24
#define ONE_SHOT               (1L << 24)
#define FOR_STANDBY            (1L << 25)


//*********************************************************************
//			Resources
//*********************************************************************
#define RESOURCE_MEMORY        0		// Physical Memory
#define RESOURCE_MMIO          1		// Memory mapped I/O
#define RESOURCE_IO            2		// I/O space
#define RESOURCE_SCIO          3		// Swiss-cheese I/O
#define RESOURCE_GPIO          4		// General-purpose I/O pin
#define RESOURCE_IRQ           5		// IRQ


  
//*********************************************************************
//			Macros
//*********************************************************************

#define SYS_GET_NEXT_MSG(p)                 sys_get_next_msg(p)
#define SYS_QUERY_MSG_QUEUE(p)              sys_query_msg_queue(p)
#define SYS_UNREGISTER_EVENT(e, p1, p2)     sys_register_event(e, p1, p2, UNREGISTER_PRIORITY)
#define SYS_REGISTER_EVENT(e, p1, p2, p)    sys_register_event(e, p1, p2, p)
#define SYS_PASS_EVENT(e, p1, p2, p3) 		 // no longer needed
#define SYS_VSM_PRESENT(vsm)                sys_vsm_present(vsm)
#define SYS_YIELD_CONTROL(p1)               sys_yield_control(p1)
#define SYS_SW_INTERRUPT(interrupt, regs)   sys_software_interrupt(interrupt, regs)
#define SYS_BROADCAST_MSG(msg, p, vsm)      sys_broadcast_msg(msg, p, vsm)
#define SYS_GET_SYSTEM_INFO(buffer)         sys_get_system_info(buffer)
#define SYS_REPORT_ERROR(err, info1, info2) sys_report_error(err, info1, info2)
#define SYS_GENERATE_IRQ(irq)               sys_generate_IRQ(irq)
#define SYS_UNLOAD_VSM()                    sys_unload_vsm()
#define SYS_LOGICAL_TO_PHYSICAL(addr)       sys_logical_to_physical(addr)
#define SYS_ALLOCATE_RESOURCE(f,p,q,r,s)    sys_resource(f, p, q, r, s)
#define SYS_DEALLOCATE_RESOURCE(f,p,q,r,s)  sys_resource((UCHAR)(f|0x80), p, q, r, s)
#define SYS_MBUS_DESCRIPTOR(addr, p)        sys_mbus_descriptor(addr, p, 0)
#define SYS_IO_DESCRIPTOR(addr, p)          sys_mbus_descriptor(addr, p, 3)
#define SYS_LOOKUP_DEVICE(id, i)            sys_lookup_device(id, i)
#define SYS_SAVE_STATE(buffer)              sys_state(0, buffer)
#define SYS_RESTORE_STATE(buffer)           sys_state(1, buffer)
#define SYS_SET_DECODE(addr, flag)          sys_address_decode(addr, flag)
#define SYS_MAP_IRQ(Source, Irq)            sys_map_irq(Source, Irq)
#define SYS_RETURN_RESULT(Data)             sys_return_result(Data)
#define SYS_DUPLICATE_VSM(MemModel)         sys_duplicate_vsm(MemModel)

#define READ_PCI_BYTE(addr)                 read_PCI_byte(addr)
#define READ_PCI_WORD(addr)                 read_PCI_word(addr)
#define READ_PCI_DWORD(addr)                read_PCI_dword(addr)
#define WRITE_PCI_BYTE(addr, data)          write_PCI_byte(addr, data)
#define WRITE_PCI_WORD(addr, data)          write_PCI_word(addr, data)
#define WRITE_PCI_DWORD(addr, data)         write_PCI_dword(addr, data)

#define WRITE_PCI_BYTE_NO_TRAP(addr, data)  write_PCI_no_trap(addr, (ULONG)data, BYTE_IO)
#define WRITE_PCI_WORD_NO_TRAP(addr, data)  write_PCI_no_trap(addr, (ULONG)data, WORD_IO)
#define WRITE_PCI_DWORD_NO_TRAP(addr, data) write_PCI_no_trap(addr, data, DWORD_IO)
#define READ_PCI_BYTE_NO_TRAP(addr)         ((UCHAR)read_PCI_no_trap(addr, BYTE_IO))
#define READ_PCI_WORD_NO_TRAP(addr)         ((USHORT)read_PCI_no_trap(addr, WORD_IO))
#define READ_PCI_DWORD_NO_TRAP(addr)        read_PCI_no_trap(addr, DWORD_IO)

#define WRITE_MEMORY(addr, data)            write_flat(addr, data)
#define READ_MEMORY(addr)                   read_flat(addr)

#define ENTER_CRITICAL_SECTION              EnterCriticalSection();
#define EXIT_CRITICAL_SECTION               ExitCriticalSection();



void __pascal sys_register_event(EVENT, ULONG, ULONG, USHORT);
void __pascal sys_software_interrupt(USHORT, INT_REGS *);
void __pascal sys_broadcast_msg(MSG, void *, USHORT);
void __pascal sys_yield_control(ULONG);
void __pascal sys_get_system_info(void *);
void __pascal sys_generate_IRQ(USHORT);
void __pascal sys_state(USHORT, void *);
void __pascal sys_address_decode(USHORT, USHORT);
void __pascal sys_map_irq(UCHAR, UCHAR); 
void __pascal sys_return_result(ULONG);
void __pascal sys_get_descriptor(USHORT, void *);
void __pascal sys_set_descriptor(USHORT, void *);
void __pascal sys_set_header_data(USHORT, ULONG);
void __pascal sys_set_register(USHORT, ULONG);
void __pascal sys_set_virtual_register(USHORT, USHORT);
void __pascal sys_report_error(USHORT, ULONG, ULONG);

void __pascal write_PCI_byte(ULONG, UCHAR);
void __pascal write_PCI_word(ULONG, USHORT);
void __pascal write_PCI_dword(ULONG, ULONG);
void __pascal write_PCI_no_trap(ULONG, ULONG, USHORT);

void EnterCriticalSection(void);
void ExitCriticalSection(void);
void sys_fast_path_return(void);
void sys_unload_vsm(void);
void __pascal sys_duplicate_vsm(USHORT);

void __pascal write_flat(ULONG, ULONG);
ULONG __pascal read_flat(ULONG);
UCHAR  __pascal sys_vsm_present(UCHAR);
USHORT __pascal sys_get_virtual_register(USHORT);
ULONG  __pascal sys_get_header_data(USHORT);
ULONG  __pascal sys_get_register(USHORT);
UCHAR  __pascal read_PCI_byte(ULONG);
USHORT __pascal read_PCI_word(ULONG);
ULONG  __pascal read_PCI_dword(ULONG);
ULONG  __pascal read_PCI_no_trap(ULONG, USHORT);
ULONG  __pascal sys_logical_to_physical(void *);
ULONG  __pascal sys_resource(UCHAR, USHORT, ULONG, USHORT, USHORT);
ULONG  __pascal sys_mbus_descriptor(USHORT, ULONG *, USHORT);
ULONG  __pascal sys_lookup_device(USHORT, USHORT);
MSG    sys_get_next_msg(void *);
MSG    sys_query_msg_queue(void *);

// Macros for use by VSMs to access the non-SMM context
#define SET_HEADER_DATA(reg, data)   sys_set_header_data(reg, data)
#define GET_HEADER_DATA(reg)         (ULONG)sys_get_header_data(reg)
#define GET_DESCRIPTOR(reg, buffer)  sys_get_descriptor(reg, buffer);
#define SET_DESCRIPTOR(reg, buffer)  sys_set_descriptor(reg, buffer);
#define GET_REGISTER(reg)            (ULONG)sys_get_register(reg)
#define SET_REGISTER(reg, data)      sys_set_register(reg, data)
#define SET_EAX(data)                SET_REGISTER(R_EAX, (ULONG) (data))
#define SET_AX(data)                 SET_REGISTER(R_AX,  (USHORT)(data))
#define SET_AL(data)                 SET_REGISTER(R_AL,  (UCHAR) (data))
#define SET_AH(data)                 SET_REGISTER(R_AH,  (UCHAR) (data))
#define SET_EFLAGS(data)             SET_HEADER_DATA(R_EFLAGS, data)
#define GET_EAX()                    ((ULONG) GET_REGISTER(R_EAX))
#define GET_AX()                     ((USHORT)GET_REGISTER(R_AX))
#define GET_AL()                     ((UCHAR) GET_REGISTER(R_AL))
#define GET_AH()                     ((UCHAR) GET_REGISTER(R_AH))
#define GET_EFLAGS()                 (GET_HEADER_DATA(R_EFLAGS))


// Macros for accessing virtual registers
#define GET_VIRTUAL_REGISTER(reg)          (USHORT)sys_get_virtual_register(reg)
#define SET_VIRTUAL_REGISTER(reg, data)    sys_set_virtual_register(reg, data)


//*********************************************************************
//			Error Codes
//*********************************************************************

#define ERR_UNDEF_EVENT		1		// Attempt to register an undefined event
//#define ERR_SCHEDULER		2		// Scheduler error
#define ERR_BAD_PARAMETER		3		// Illegal system call parameter
#define ERR_RESOURCE_CONFLICT	4		// Multiple VSMs requested conflicting resources
#define ERR_UNHANDLED_EVENT	5		// An event occurred that no VSM handled
#define ERR_INVALID_EVENT		6		// SysMgr attempted to send an invalid event
//#define ERR_TIME_LIMIT		7		// A VSM exceeded its allotted runtime
#define ERR_REGISTRATION_LOST	8		// A registered event is lost due to too many event registrations
#define ERR_HW_MISMATCH		9		// A VSM could not find the correct hardware (e.g. OHCI)
#define ERR_BAD_DESCRIPTOR		0x0A	// A descriptor in a VSM header is not valid
//#define ERR_MSG_QUEUE_FULL	0x0B	// A VSM's message queue is full
//#define ERR_MULTIPLE_EVENT   0x0C	// A VSM attempted to register the same event twice
#define ERR_UNREGISTRATION     0x0D	// A VSM attempted to unregister an event for which it was not registered
#define ERR_UNREGISTERED_EVENT 0x0E	// An event occurred for which no VSM is registered
#define ERR_MISALIGNED_IO		0x0F	// An misaligned I/O access occurred
//#define ERR_UNEXPECTED_EVENT 0x10    // A handler routine was passed an unexpected SMI event
//#define ERR_BAD_VSM			0x11	// A VSM header doesn't look right (no signature, etc.)
#define ERR_NESTED_ACCESS		0x12	// A VSM directly accessed a ACPI or virtual register
//#define ERR_BAD_MSG			0x13	// An attempt was made to send an illegal message code
//#define ERR_UNHANDLED_VIRTUAL 0x14	// An access was made by a VSM to an unhandled virtual register
#define ERR_BAD_INTERRUPT      0x15    // A VSM attempted to call an illegal INT vector
#define ERR_ILLEGAL_MACRO      0x16    // Illegal use of GET/SET_REGISTER or GET/SET_HEADER_DATA macros
#define ERR_UNDEF_SYS_CALL		0x17	// Undefined system call
//#define ERR_BAD_POWER_STATE	0x18	// Invalid power state
#define ERR_BAD_VR_ACCESS      0x19	// Access to undefined VR class by an application
#define ERR_UNDEF_VIRTUAL_REG	0x1A	// Access to undefined VR class by a VSM
//#define ERR_UNSUPPORTED_CHIPSET 0x1B // This chipset is not supported
#define ERR_PCI_TRAP           0x1C    // A VSM requested an unsupported PCI trap
#define ERR_RESOURCE_NOT_FOUND 0x1D    // A VSM requested an unsupported resource
#define ERR_NO_MORE_DESCRIPTORS 0x1E   // Out of MBIU descriptors
//#define ERR_INTERNAL_ERROR    0x1F   // System error, e.g. inconsistent data structure
#define ERR_DATA_STRUCTURE      0x20	// A system structure is too small






// Used as 2nd parameter to SYS_SET_DECODE macro:
#define POSITIVE_DECODE			1
#define SUBTRACTIVE_DECODE		0




//****************************************************************************************************
#define FROM_HEADER            0x2000
#define WORD_SIZE              0x4000
#define DWORD_SIZE             0x8000




// Field names for GET_REGISTER and SET_REGISTER macros
// These offsets must match the register order on the stack (PUSHAD)

#define R_DI			 0   + WORD_SIZE 
#define R_EDI			 0   + DWORD_SIZE
				
#define R_SI			 4   + WORD_SIZE
#define R_ESI			 4   + DWORD_SIZE

#define R_BP			 8   + WORD_SIZE
#define R_EBP			 8   + DWORD_SIZE
				
#define R_BL			16
#define R_BH			R_BL + 1
#define R_BX			R_BL + WORD_SIZE
#define R_EBX			R_BL + DWORD_SIZE

#define R_DL			20
#define R_DH			R_DL + 1
#define R_DX			R_DL + WORD_SIZE
#define R_EDX			R_DL + DWORD_SIZE
		
#define R_CL			24
#define R_CH			R_CL + 1
#define R_CX			R_CL + WORD_SIZE
#define R_ECX			R_CL + DWORD_SIZE

#define R_AL			28
#define R_AH			R_AL + 1
#define R_AX			R_AL + WORD_SIZE
#define R_EAX			R_AL + DWORD_SIZE

#define R_SP			32   + WORD_SIZE
#define R_ESP			32   + DWORD_SIZE


// Segment registers
// NOTE: offset points to .selector field
#define DESCRIPTOR_SIZE 10 // sizeof(Descriptor)
#define R_SS			36-2 + DESCRIPTOR_SIZE + WORD_SIZE
#define R_DS			R_SS + DESCRIPTOR_SIZE
#define R_ES			R_DS + DESCRIPTOR_SIZE
#define R_FS			R_ES + DESCRIPTOR_SIZE
#define R_GS			R_FS + DESCRIPTOR_SIZE

// Fields from SMM header
#define WRITE_DATA		0x08 + DWORD_SIZE + FROM_HEADER
#define IO_ADDRESS		0x0C + WORD_SIZE  + FROM_HEADER
#define DATA_SIZE		0x0E              + FROM_HEADER
#define SMM_FLAGS		0x10 + WORD_SIZE  + FROM_HEADER
#define CS_LIMIT		0x14 + DWORD_SIZE + FROM_HEADER
#define CS_BASE	   	0x18 + DWORD_SIZE + FROM_HEADER
#define CS_SELECTOR	0x1C + WORD_SIZE  + FROM_HEADER
#define CS_ATTR		0x1E + WORD_SIZE  + FROM_HEADER 
#define R_CS		0x1C + WORD_SIZE  + FROM_HEADER
#define R_IP		0x20 + WORD_SIZE  + FROM_HEADER
#define R_EIP		0x20 + DWORD_SIZE + FROM_HEADER
#define CURRENT_EIP  	0x24 + DWORD_SIZE + FROM_HEADER
#define R_CR0		0x28 + DWORD_SIZE + FROM_HEADER
#define R_EFLAGS   	0x2C + DWORD_SIZE + FROM_HEADER
  #define EFLAGS_CF    0x0001
  #define EFLAGS_ZF    0x0040
  #define EFLAGS_IF	0x0200
  #define EFLAGS_DF    0x0400
#define R_DR7 	   	0x30 + DWORD_SIZE + FROM_HEADER






typedef struct {
  ULONG  Chipset_Base;
  USHORT Chipset_ID;
  USHORT Chipset_Rev;
  USHORT CPU_ID;
  USHORT CPU_Revision;
  USHORT CPU_MHz;
  ULONG  SystemMemory;		// Units = bytes
  ULONG  VSA_Location;		// Physical location
  USHORT VSA_Size;			// Units = KB
  USHORT PCI_MHz;
  USHORT DRAM_MHz;
} Hardware;