/*
 * Copyright (c) 2026, Chloe M.
 * Provided under the BSD-3 clause.
 *
 * Description: Task state segment
 * Author:      Chloe M.
 */

#ifndef _MACHINE_TSS_H_
#define _MACHINE_TSS_H_ 1

#include <ptdef.h>

/*
 * Represents used interrupt stack table indices
 *
 * @IST_RESERVED: This is not used
 * @IST_NMI:      Stack for NMIs
 * @IST_SCHED:    Stack for scheduler
 */
typedef enum {
    IST_RESERVED,
    IST_NMI,
    IST_SCHED
} IST_INDEX;

/*
 * Represents a platform task state segment
 *
 * Refer to section 8.7 of the Intel SDM
 */
typedef struct PACKED {
    ULONG Reserved;
    ULONG Rsp0Low;
    ULONG Rsp0High;
    ULONG Rsp1Low;
    ULONG Rsp1High;
    ULONG Rsp2Low;
    ULONG Rsp2High;
    ULONG Reserved1;
    ULONG Reserved2;
    ULONG Ist1Low;
    ULONG Ist1High;
    ULONG Ist2Low;
    ULONG Ist2High;
    ULONG Ist3Low;
    ULONG Ist3High;
    ULONG Ist4Low;
    ULONG Ist4High;
    ULONG Ist5Low;
    ULONG Ist5High;
    ULONG Ist6Low;
    ULONG Ist6High;
    ULONG Ist7Low;
    ULONG Ist7High;
    ULONG Reserved3;
    ULONG Reserved4;
    USHORT Reserved5;
    USHORT IoBitmap;
} TSS_ENTRY;

/*
 * Task state segment descriptor within GDT
 *
 * Refer to section 8.2.3 of the Intel SDM
 */
typedef struct PACKED {
    USHORT SegmentLimit;
    USHORT BaseLow16;
    UCHAR BaseMid8;
    UCHAR Type : 4;
    UCHAR Zero : 1;
    UCHAR Dpl  : 2;
    UCHAR Present : 1;
    UCHAR SegLimitHigh : 4;
    UCHAR Avl : 1;
    UCHAR Unused : 2;
    UCHAR Gran : 1;
    UCHAR BaseHighMid8;
    ULONG BaseHigh32;
    ULONG Reserved;
} TSS_DESCRIPTOR;

/*
 * Allocate an interrupt stack table entry
 *
 * @IstIndex:  Interrupt stack table index
 * @StackSize: Size of stack to allocate
 */
VOID MdTssAllocIst(UCHAR IstIndex, USIZE StackSize);

/*
 * Initialize the task state segment
 *
 * @Descriptor:   Task state segment desciptor
 */
VOID MdTssInit(TSS_DESCRIPTOR *Descriptor);

#endif  /* !_MACHINE_TSS_H_ */
