mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2026-01-21 09:10:37 -05:00
Adding support for Xen for x86 (32bit and 64bit)
This commit is contained in:
parent
14b30f209f
commit
dd83fb7347
21 changed files with 6421 additions and 0 deletions
128
portable/GCC/XEN_x86/IA32/ISR_Support.h
Normal file
128
portable/GCC/XEN_x86/IA32/ISR_Support.h
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
.extern ulTopOfSystemStack
|
||||
.extern ulInterruptNesting
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
.macro portFREERTOS_INTERRUPT_ENTRY
|
||||
|
||||
/* Save general purpose registers. */
|
||||
pusha
|
||||
|
||||
/* If ulInterruptNesting is zero the rest of the task context will need
|
||||
saving and a stack switch might be required. */
|
||||
movl ulInterruptNesting, %eax
|
||||
test %eax, %eax
|
||||
jne 2f
|
||||
|
||||
/* Interrupts are not nested, so save the rest of the task context. */
|
||||
.if configSUPPORT_FPU == 1
|
||||
|
||||
/* If the task has a buffer allocated to save the FPU context then
|
||||
save the FPU context now. */
|
||||
movl pucPortTaskFPUContextBuffer, %eax
|
||||
test %eax, %eax
|
||||
je 1f
|
||||
fnsave ( %eax ) /* Save FLOP context into ucTempFPUBuffer array. */
|
||||
fwait
|
||||
|
||||
1:
|
||||
/* Save the address of the FPU context, if any. */
|
||||
push pucPortTaskFPUContextBuffer
|
||||
|
||||
.endif /* configSUPPORT_FPU */
|
||||
|
||||
/* Find the TCB. */
|
||||
movl pxCurrentTCB, %eax
|
||||
|
||||
/* Stack location is first item in the TCB. */
|
||||
movl %esp, (%eax)
|
||||
|
||||
/* Switch stacks. */
|
||||
movl ulTopOfSystemStack, %esp
|
||||
movl %esp, %ebp
|
||||
|
||||
2:
|
||||
/* Increment nesting count. */
|
||||
add $1, ulInterruptNesting
|
||||
|
||||
.endm
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
.macro portINTERRUPT_EPILOGUE
|
||||
|
||||
cli
|
||||
sub $1, ulInterruptNesting
|
||||
|
||||
/* If the nesting has unwound to zero. */
|
||||
movl ulInterruptNesting, %eax
|
||||
test %eax, %eax
|
||||
jne 2f
|
||||
|
||||
/* If a yield was requested then select a new TCB now. */
|
||||
movl ulPortYieldPending, %eax
|
||||
test %eax, %eax
|
||||
je 1f
|
||||
movl $0, ulPortYieldPending
|
||||
call vTaskSwitchContext
|
||||
|
||||
1:
|
||||
/* Stack location is first item in the TCB. */
|
||||
movl pxCurrentTCB, %eax
|
||||
movl (%eax), %esp
|
||||
|
||||
.if configSUPPORT_FPU == 1
|
||||
|
||||
/* Restore address of task's FPU context buffer. */
|
||||
pop pucPortTaskFPUContextBuffer
|
||||
|
||||
/* If the task has a buffer allocated in which its FPU context is saved,
|
||||
then restore it now. */
|
||||
movl pucPortTaskFPUContextBuffer, %eax
|
||||
test %eax, %eax
|
||||
je 1f
|
||||
frstor ( %eax )
|
||||
1:
|
||||
.endif
|
||||
|
||||
2:
|
||||
popa
|
||||
|
||||
.endm
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
.macro portFREERTOS_INTERRUPT_EXIT
|
||||
|
||||
portINTERRUPT_EPILOGUE
|
||||
/* EOI. */
|
||||
movl $0x00, (0xFEE000B0)
|
||||
iret
|
||||
|
||||
.endm
|
||||
2
portable/GCC/XEN_x86/IA32/README.md
Normal file
2
portable/GCC/XEN_x86/IA32/README.md
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# Description
|
||||
This folder contain source for FreeRTOS port for x86_32.
|
||||
627
portable/GCC/XEN_x86/IA32/port.c
Normal file
627
portable/GCC/XEN_x86/IA32/port.c
Normal file
|
|
@ -0,0 +1,627 @@
|
|||
/*
|
||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <limits.h>
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "io.h"
|
||||
#include "ioapic.h"
|
||||
#include "stdio.h"
|
||||
#include "IRQ.h"
|
||||
|
||||
|
||||
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||
/* Check the configuration. */
|
||||
#if ( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||
#endif
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
#if ( ( configMAX_API_CALL_INTERRUPT_PRIORITY > portMAX_PRIORITY ) || ( configMAX_API_CALL_INTERRUPT_PRIORITY < 2 ) )
|
||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be between 2 and 15
|
||||
#endif
|
||||
|
||||
#if ( ( configSUPPORT_FPU == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) )
|
||||
#error configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 to use this port with an FPU
|
||||
#endif
|
||||
|
||||
/* A critical section is exited when the critical section nesting count reaches
|
||||
* this value. */
|
||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||
|
||||
/* Tasks are not created with a floating point context, but can be given a
|
||||
* floating point context after they have been created. A variable is stored as
|
||||
* part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||
* does not have an FPU context, or any other value if the task does have an FPU
|
||||
* context. */
|
||||
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
||||
|
||||
/* Only the IF bit is set so tasks start with interrupts enabled. */
|
||||
#define portINITIAL_EFLAGS ( 0x200UL )
|
||||
|
||||
/* Error interrupts are at the highest priority vectors. */
|
||||
#define portAPIC_LVT_ERROR_VECTOR ( 0xfe )
|
||||
#define portAPIC_SPURIOUS_INT_VECTOR ( 0xff )
|
||||
#define portAPIC_DEBUG_SERIAL_INT_VECTOR ( 0x24 )
|
||||
|
||||
/* EFLAGS bits. */
|
||||
#define portEFLAGS_IF ( 0x200UL )
|
||||
|
||||
/* FPU context size if FSAVE is used. */
|
||||
#define portFPU_CONTEXT_SIZE_BYTES 108
|
||||
|
||||
/* The expected size of each entry in the IDT. Used to check structure packing
|
||||
* is set correctly. */
|
||||
#define portEXPECTED_IDT_ENTRY_SIZE 8
|
||||
|
||||
/* Default flags setting for entries in the IDT. */
|
||||
#define portIDT_FLAGS ( 0x8E )
|
||||
|
||||
/* This is the lowest possible ISR vector available to application code. */
|
||||
#define portAPIC_MIN_ALLOWABLE_VECTOR ( 0x20 )
|
||||
|
||||
/* If configASSERT() is defined then the system stack is filled with this value
|
||||
* to allow for a crude stack overflow check. */
|
||||
#define portSTACK_WORD ( 0xecececec )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Starts the first task executing.
|
||||
*/
|
||||
extern void vPortStartFirstTask( void );
|
||||
|
||||
/*
|
||||
* Used to catch tasks that attempt to return from their implementing function.
|
||||
*/
|
||||
static void prvTaskExitError( void );
|
||||
|
||||
/*
|
||||
* Complete one descriptor in the IDT.
|
||||
*/
|
||||
static void prvSetInterruptGate( uint8_t ucNumber,
|
||||
ISR_Handler_t pxHandlerFunction,
|
||||
uint8_t ucFlags );
|
||||
|
||||
/*
|
||||
* The default handler installed in each IDT position.
|
||||
*/
|
||||
extern void vPortCentralInterruptWrapper( void );
|
||||
|
||||
/*
|
||||
* Handler for portYIELD().
|
||||
*/
|
||||
extern void vPortYieldCall( void );
|
||||
|
||||
/*
|
||||
* Configure the APIC to generate the RTOS tick.
|
||||
*/
|
||||
static void prvSetupLAPIC( void );
|
||||
|
||||
/*
|
||||
* Tick interrupt handler.
|
||||
*/
|
||||
extern void vPortTimerHandler( void );
|
||||
extern void vPortIRQHandler( void );
|
||||
extern void vHypervisorCallback( void );
|
||||
extern void vSCIHandler( void );
|
||||
extern void vTestInterruptHandler( void );
|
||||
void enable_sci(void);
|
||||
void init_time(void);
|
||||
|
||||
/*
|
||||
* Check an interrupt vector is not too high, too low, in use by FreeRTOS, or
|
||||
* already in use by the application.
|
||||
*/
|
||||
static BaseType_t prvCheckValidityOfVectorNumber( uint32_t ulVectorNumber );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* A variable is used to keep track of the critical section nesting. This
|
||||
* variable must be initialised to a non zero value to ensure interrupts don't
|
||||
* inadvertently become unmasked before the scheduler starts. It is set to zero
|
||||
* before the first task starts executing. */
|
||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||
|
||||
/* A structure used to map the various fields of an IDT entry into separate
|
||||
* structure members. */
|
||||
struct IDTEntry
|
||||
{
|
||||
uint16_t usISRLow; /* Low 16 bits of handler address. */
|
||||
uint16_t usSegmentSelector; /* Flat model means this is not changed. */
|
||||
uint8_t ucZero; /* Must be set to zero. */
|
||||
uint8_t ucFlags; /* Flags for this entry. */
|
||||
uint16_t usISRHigh; /* High 16 bits of handler address. */
|
||||
}
|
||||
__attribute__( ( packed ) );
|
||||
typedef struct IDTEntry IDTEntry_t;
|
||||
|
||||
|
||||
/* Use to pass the location of the IDT to the CPU. */
|
||||
struct IDTPointer
|
||||
{
|
||||
uint16_t usTableLimit;
|
||||
uint32_t ulTableBase; /* The address of the first entry in xInterruptDescriptorTable. */
|
||||
}
|
||||
__attribute__( ( __packed__ ) );
|
||||
typedef struct IDTPointer IDTPointer_t;
|
||||
|
||||
/* The IDT itself. */
|
||||
static __attribute__( ( aligned( 32 ) ) ) IDTEntry_t xInterruptDescriptorTable[ portNUM_VECTORS ];
|
||||
|
||||
#if ( configUSE_COMMON_INTERRUPT_ENTRY_POINT == 1 )
|
||||
|
||||
/* A table in which application defined interrupt handlers are stored. These
|
||||
* are called by the central interrupt handler if a common interrupt entry
|
||||
* point it used. */
|
||||
static ISR_Handler_t xInterruptHandlerTable[ portNUM_VECTORS ] = { NULL };
|
||||
|
||||
#endif /* configUSE_COMMON_INTERRUPT_ENTRY_POINT */
|
||||
|
||||
#if ( configSUPPORT_FPU == 1 )
|
||||
|
||||
/* Saved as part of the task context. If pucPortTaskFPUContextBuffer is NULL
|
||||
* then the task does not have an FPU context. If pucPortTaskFPUContextBuffer is
|
||||
* not NULL then it points to a buffer into which the FPU context can be saved. */
|
||||
uint8_t * pucPortTaskFPUContextBuffer __attribute__( ( used ) ) = pdFALSE;
|
||||
|
||||
#endif /* configSUPPORT_FPU */
|
||||
|
||||
/* The stack used by interrupt handlers. */
|
||||
static uint32_t ulSystemStack[ configISR_STACK_SIZE ] __attribute__( ( used ) ) = { 0 };
|
||||
|
||||
/* Don't use the very top of the system stack so the return address
|
||||
* appears as 0 if the debugger tries to unwind the stack. */
|
||||
volatile uint32_t ulTopOfSystemStack __attribute__( ( used ) ) = ( uint32_t ) &( ulSystemStack[ configISR_STACK_SIZE - 5 ] );
|
||||
|
||||
/* If a yield is requested from an interrupt or from a critical section then
|
||||
* the yield is not performed immediately, and ulPortYieldPending is set to pdTRUE
|
||||
* instead to indicate the yield should be performed at the end of the interrupt
|
||||
* when the critical section is exited. */
|
||||
volatile uint32_t ulPortYieldPending __attribute__( ( used ) ) = pdFALSE;
|
||||
volatile uint32_t schedStart __attribute__( ( used ) ) = pdFALSE;
|
||||
|
||||
/* Counts the interrupt nesting depth. Used to know when to switch to the
|
||||
* interrupt/system stack and when to save/restore a complete context. */
|
||||
volatile uint32_t ulInterruptNesting __attribute__( ( used ) ) = 0;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t * pxPortInitialiseStack( StackType_t *pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
uint32_t ulCodeSegment;
|
||||
|
||||
/* Setup the initial stack as expected by the portFREERTOS_INTERRUPT_EXIT macro. */
|
||||
|
||||
*pxTopOfStack = 0x00;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x00;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Parameters first. */
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* There is nothing to return to so assert if attempting to use the return
|
||||
* address. */
|
||||
*pxTopOfStack = ( StackType_t ) prvTaskExitError;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* iret used to start the task pops up to here. */
|
||||
*pxTopOfStack = portINITIAL_EFLAGS;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* CS */
|
||||
__asm volatile ( "movl %%cs, %0" : "=r" ( ulCodeSegment ) );
|
||||
*pxTopOfStack = ulCodeSegment;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* First instruction in the task. */
|
||||
*pxTopOfStack = ( StackType_t ) pxCode;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* General purpose registers as expected by a POPA instruction. */
|
||||
*pxTopOfStack = 0xEA;
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = 0xEC;
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = 0xED1; /* EDX */
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = 0xEB1; /* EBX */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Hole for ESP. */
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = 0x00; /* EBP */
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = 0xE5; /* ESI */
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = 0xeeeeeeee; /* EDI */
|
||||
|
||||
#if ( configSUPPORT_FPU == 1 )
|
||||
{
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Buffer for FPU context, which is initialised to NULL as tasks are not
|
||||
* created with an FPU context. */
|
||||
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
||||
}
|
||||
#endif /* configSUPPORT_FPU */
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
static void prvSetInterruptGate( uint8_t ucNumber,
|
||||
ISR_Handler_t pxHandlerFunction,
|
||||
uint8_t ucFlags )
|
||||
{
|
||||
uint16_t usCodeSegment;
|
||||
uint32_t ulBase = ( uint32_t ) pxHandlerFunction;
|
||||
|
||||
xInterruptDescriptorTable[ ucNumber ].usISRLow = ( uint16_t ) ( ulBase & USHRT_MAX );
|
||||
xInterruptDescriptorTable[ ucNumber ].usISRHigh = ( uint16_t ) ( ( ulBase >> 16UL ) & USHRT_MAX );
|
||||
|
||||
/* When the flat model is used the CS will never change. */
|
||||
__asm volatile ( "mov %%cs, %0" : "=r" ( usCodeSegment ) );
|
||||
xInterruptDescriptorTable[ ucNumber ].usSegmentSelector = usCodeSegment;
|
||||
xInterruptDescriptorTable[ ucNumber ].ucZero = 0;
|
||||
xInterruptDescriptorTable[ ucNumber ].ucFlags = ucFlags | 0x60;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
#define PIC1 0x20
|
||||
#define PIC2 0xA0
|
||||
#define PIC1_COMMAND PIC1
|
||||
#define PIC1_DATA (PIC1+1)
|
||||
#define PIC2_COMMAND PIC2
|
||||
#define PIC2_DATA (PIC2+1)
|
||||
void vPortSetupIDT( void )
|
||||
{
|
||||
extern void vPortAPICErrorHandlerWrapper( void );
|
||||
extern void vPortAPICSpuriousHandler( void );
|
||||
|
||||
// Disable interrupts from 8259
|
||||
outb(PIC1_COMMAND, 0x21);
|
||||
outb(PIC1_DATA, 0xFF);
|
||||
outb(PIC1_COMMAND, 0x22);
|
||||
outb(PIC1_DATA, 0xFF);
|
||||
uint32_t ulNum;
|
||||
IDTPointer_t xIDT;
|
||||
#if ( configUSE_COMMON_INTERRUPT_ENTRY_POINT == 1 )
|
||||
{
|
||||
for( ulNum = 0; ulNum < portNUM_VECTORS; ulNum++ )
|
||||
{
|
||||
/* If a handler has not already been installed on this vector. */
|
||||
if( ( xInterruptDescriptorTable[ ulNum ].usISRLow == 0x00 ) && ( xInterruptDescriptorTable[ ulNum ].usISRHigh == 0x00 ) )
|
||||
{
|
||||
prvSetInterruptGate( ( uint8_t ) ulNum, vPortCentralInterruptWrapper, portIDT_FLAGS );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* configUSE_COMMON_INTERRUPT_ENTRY_POINT */
|
||||
|
||||
/* Install APIC timer ISR vector. */
|
||||
prvSetInterruptGate( ( uint8_t ) 50, vPortTimerHandler, portIDT_FLAGS );
|
||||
|
||||
/* Install API error handler. */
|
||||
prvSetInterruptGate( ( uint8_t ) portAPIC_LVT_ERROR_VECTOR, vPortAPICErrorHandlerWrapper, portIDT_FLAGS );
|
||||
|
||||
/* Install Yield handler. */
|
||||
prvSetInterruptGate( ( uint8_t ) portAPIC_YIELD_INT_VECTOR, vPortYieldCall, portIDT_FLAGS );
|
||||
|
||||
/* Install spurious interrupt vector. */
|
||||
prvSetInterruptGate( ( uint8_t ) portAPIC_SPURIOUS_INT_VECTOR, vPortAPICSpuriousHandler, portIDT_FLAGS );
|
||||
|
||||
/* Install Vector for Debug Serial Port */
|
||||
prvSetInterruptGate( ( uint8_t ) portAPIC_DEBUG_SERIAL_INT_VECTOR, vPortIRQHandler, portIDT_FLAGS );
|
||||
prvSetInterruptGate( ( uint8_t ) 37, vHypervisorCallback, portIDT_FLAGS );
|
||||
prvSetInterruptGate( ( uint8_t ) 41, vSCIHandler, portIDT_FLAGS );
|
||||
prvSetInterruptGate( ( uint8_t ) 96, vTestInterruptHandler, portIDT_FLAGS );
|
||||
|
||||
/* Set IDT address. */
|
||||
xIDT.ulTableBase = ( uint32_t ) xInterruptDescriptorTable;
|
||||
xIDT.usTableLimit = sizeof( xInterruptDescriptorTable ) - 1;
|
||||
|
||||
/* Set IDT in CPU. */
|
||||
__asm volatile ( "lidt %0" ::"m" ( xIDT ) );
|
||||
//__asm volatile ("ltr %w0" :: "rm" (7 * 8));
|
||||
|
||||
|
||||
prvSetupLAPIC();
|
||||
set_ioapic_irq_mask(portAPIC_DEBUG_SERIAL_INT_VECTOR-0x20,0);
|
||||
set_ioapic_irq_mask(portAPIC_TIMER_INT_VECTOR-0x20,0);
|
||||
enable_sci();
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvTaskExitError( void )
|
||||
{
|
||||
/* A function that implements a task must not exit or attempt to return to
|
||||
* its caller as there is nothing to return to. If a task wants to exit it
|
||||
* should instead call vTaskDelete( NULL ).
|
||||
*
|
||||
* Artificially force an assert() to be triggered if configASSERT() is
|
||||
* defined, then stop here so application writers can catch the error. */
|
||||
configASSERT( ulCriticalNesting == ~0UL );
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
for( ; ; )
|
||||
{
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
static void prvSetupLAPIC( void )
|
||||
{
|
||||
extern void vPortAPICErrorHandlerWrapper( void );
|
||||
extern void vPortAPICSpuriousHandler( void );
|
||||
|
||||
/* Initialise LAPIC to a well known state. */
|
||||
portAPIC_LDR = 0xFFFFFFFF;
|
||||
portAPIC_LDR = ( ( portAPIC_LDR & 0x00FFFFFF ) | 0x00000001 );
|
||||
portAPIC_LVT_TIMER = portAPIC_DISABLE;
|
||||
portAPIC_LVT_PERF = portAPIC_NMI;
|
||||
portAPIC_LVT_LINT0 = portAPIC_DISABLE;
|
||||
portAPIC_LVT_LINT1 = portAPIC_DISABLE;
|
||||
portAPIC_TASK_PRIORITY = 0;
|
||||
|
||||
/* Enable the APIC, mapping the spurious interrupt at the same time. */
|
||||
portAPIC_SPURIOUS_INT = portAPIC_SPURIOUS_INT_VECTOR | portAPIC_ENABLE_BIT;
|
||||
|
||||
/* Set timer error vector. */
|
||||
portAPIC_LVT_ERROR = portAPIC_LVT_ERROR_VECTOR;
|
||||
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
BaseType_t xWord;
|
||||
|
||||
/* Some versions of GCC require the -mno-ms-bitfields command line option
|
||||
* for packing to work. */
|
||||
configASSERT( sizeof( struct IDTEntry ) == portEXPECTED_IDT_ENTRY_SIZE );
|
||||
|
||||
/* Fill part of the system stack with a known value to help detect stack
|
||||
* overflow. A few zeros are left so GDB doesn't get confused unwinding
|
||||
* the stack. */
|
||||
for( xWord = 0; xWord < configISR_STACK_SIZE - 20; xWord++ )
|
||||
{
|
||||
ulSystemStack[ xWord ] = portSTACK_WORD;
|
||||
}
|
||||
|
||||
/* Initialise Interrupt Descriptor Table (IDT). */
|
||||
vPortSetupIDT();
|
||||
|
||||
init_time();
|
||||
|
||||
|
||||
/* Make sure the stack used by interrupts is aligned. */
|
||||
ulTopOfSystemStack &= ~portBYTE_ALIGNMENT_MASK;
|
||||
ulCriticalNesting = 0;
|
||||
|
||||
|
||||
/* Should not return from the following function as the scheduler will then
|
||||
* be executing the tasks. */
|
||||
vPortStartFirstTask();
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
* Artificially force an assert. */
|
||||
configASSERT( ulCriticalNesting == 1000UL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
if( ulCriticalNesting == 0 )
|
||||
{
|
||||
#if ( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY )
|
||||
{
|
||||
__asm volatile ( "cli" );
|
||||
}
|
||||
#else
|
||||
{
|
||||
portAPIC_TASK_PRIORITY = portMAX_API_CALL_PRIORITY;
|
||||
configASSERT( portAPIC_TASK_PRIORITY == portMAX_API_CALL_PRIORITY );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Now that interrupts are disabled, ulCriticalNesting can be accessed
|
||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
* portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortExitCritical( void )
|
||||
{
|
||||
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Decrement the nesting count as the critical section is being
|
||||
* exited. */
|
||||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then all interrupt
|
||||
* priorities must be re-enabled. */
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Critical nesting has reached zero so all interrupt priorities
|
||||
* should be unmasked. */
|
||||
#if ( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY )
|
||||
{
|
||||
__asm volatile ( "sti" );
|
||||
}
|
||||
#else
|
||||
{
|
||||
portAPIC_TASK_PRIORITY = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If a yield was pended from within the critical section then
|
||||
* perform the yield now. */
|
||||
if( ulPortYieldPending != pdFALSE )
|
||||
{
|
||||
ulPortYieldPending = pdFALSE;
|
||||
__asm volatile ( portYIELD_INTERRUPT );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint32_t ulPortSetInterruptMask( void )
|
||||
{
|
||||
volatile uint32_t ulOriginalMask;
|
||||
|
||||
/* Set mask to max syscall priority. */
|
||||
#if ( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY )
|
||||
{
|
||||
/* Return whether interrupts were already enabled or not. Pop adjusts
|
||||
* the stack first. */
|
||||
__asm volatile ( "pushf \t\n"
|
||||
"pop %0 \t\n"
|
||||
"cli "
|
||||
: "=rm" ( ulOriginalMask )::"memory" );
|
||||
|
||||
ulOriginalMask &= portEFLAGS_IF;
|
||||
}
|
||||
#else
|
||||
{
|
||||
/* Return original mask. */
|
||||
ulOriginalMask = portAPIC_TASK_PRIORITY;
|
||||
portAPIC_TASK_PRIORITY = portMAX_API_CALL_PRIORITY;
|
||||
configASSERT( portAPIC_TASK_PRIORITY == portMAX_API_CALL_PRIORITY );
|
||||
}
|
||||
#endif /* if ( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY ) */
|
||||
|
||||
return ulOriginalMask;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortClearInterruptMask( uint32_t ulNewMaskValue )
|
||||
{
|
||||
#if ( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY )
|
||||
{
|
||||
if( ulNewMaskValue != pdFALSE )
|
||||
{
|
||||
__asm volatile ( "sti" );
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
portAPIC_TASK_PRIORITY = ulNewMaskValue;
|
||||
configASSERT( portAPIC_TASK_PRIORITY == ulNewMaskValue );
|
||||
}
|
||||
#endif /* if ( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY ) */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configSUPPORT_FPU == 1 )
|
||||
|
||||
void vPortTaskUsesFPU( void )
|
||||
{
|
||||
/* A task is registering the fact that it needs an FPU context. Allocate a
|
||||
* buffer into which the context can be saved. */
|
||||
pucPortTaskFPUContextBuffer = ( uint8_t * ) pvPortMalloc( portFPU_CONTEXT_SIZE_BYTES );
|
||||
configASSERT( pucPortTaskFPUContextBuffer );
|
||||
|
||||
/* Initialise the floating point registers. */
|
||||
__asm volatile ( "fninit" );
|
||||
}
|
||||
|
||||
#endif /* configSUPPORT_FPU */
|
||||
|
||||
void (*test_irq_handler)(void) = NULL;
|
||||
void process_test_interrupt() {
|
||||
if (test_irq_handler) test_irq_handler();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortAPICErrorHandler( void )
|
||||
{
|
||||
/* Variable to hold the APIC error status for viewing in the debugger. */
|
||||
volatile uint32_t ulErrorStatus = 0;
|
||||
|
||||
portAPIC_ERROR_STATUS = 0;
|
||||
ulErrorStatus = portAPIC_ERROR_STATUS;
|
||||
( void ) ulErrorStatus;
|
||||
|
||||
/* Force an assert. */
|
||||
configASSERT( ulCriticalNesting == ~0UL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_COMMON_INTERRUPT_ENTRY_POINT == 1 )
|
||||
|
||||
void vPortCentralInterruptHandler( uint32_t ulVector )
|
||||
{
|
||||
if( ulVector < portNUM_VECTORS )
|
||||
{
|
||||
uint32_t irq = ulVector - 0x20;
|
||||
INT_HANDLER irq_handler = get_int_handler(irq);
|
||||
if (irq_handler != NULL) {
|
||||
irq_handler();
|
||||
}
|
||||
}
|
||||
/* Check for a system stack overflow. */
|
||||
configASSERT( ulSystemStack[ 10 ] == portSTACK_WORD );
|
||||
configASSERT( ulSystemStack[ 12 ] == portSTACK_WORD );
|
||||
configASSERT( ulSystemStack[ 14 ] == portSTACK_WORD );
|
||||
}
|
||||
|
||||
#endif /* configUSE_COMMON_INTERRUPT_ENTRY_POINT */
|
||||
/*-----------------------------------------------------------*/
|
||||
void vGenerateYieldInterrupt( void )
|
||||
{
|
||||
__asm volatile ( portYIELD_INTERRUPT );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
int vHaltCPU(void)
|
||||
{
|
||||
__asm volatile ("hlt");
|
||||
return 1;
|
||||
}
|
||||
351
portable/GCC/XEN_x86/IA32/portASM.S
Normal file
351
portable/GCC/XEN_x86/IA32/portASM.S
Normal file
|
|
@ -0,0 +1,351 @@
|
|||
/*
|
||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
.file "portASM.S"
|
||||
#include "FreeRTOSConfig.h"
|
||||
#include "ISR_Support.h"
|
||||
|
||||
.extern pxCurrentTCB
|
||||
.extern vTaskSwitchContext
|
||||
.extern vPortCentralInterruptHandler
|
||||
.extern xTaskIncrementTick
|
||||
.extern vPortAPICErrorHandler
|
||||
.extern pucPortTaskFPUContextBuffer
|
||||
.extern ulPortYieldPending
|
||||
.extern process_sci
|
||||
|
||||
.global vPortStartFirstTask
|
||||
.global vPortCentralInterruptWrapper
|
||||
.global vPortAPICErrorHandlerWrapper
|
||||
.global vPortTimerHandler
|
||||
.global vPortYieldCall
|
||||
.global vPortIRQHandler
|
||||
.global vHypervisorCallback
|
||||
.global vSCIHandler
|
||||
.global vTestInterruptHandler
|
||||
.global vPortAPICSpuriousHandler
|
||||
|
||||
.text
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
.align 4
|
||||
.func vPortYieldCall
|
||||
vPortYieldCall:
|
||||
/* Save general purpose registers. */
|
||||
pusha
|
||||
|
||||
.if configSUPPORT_FPU == 1
|
||||
|
||||
/* If the task has a buffer allocated to save the FPU context then save
|
||||
the FPU context now. */
|
||||
movl pucPortTaskFPUContextBuffer, %eax
|
||||
test %eax, %eax
|
||||
je 1f
|
||||
fnsave ( %eax )
|
||||
fwait
|
||||
|
||||
1:
|
||||
|
||||
/* Save the address of the FPU context, if any. */
|
||||
push pucPortTaskFPUContextBuffer
|
||||
|
||||
.endif /* configSUPPORT_FPU */
|
||||
|
||||
/* Find the TCB. */
|
||||
movl pxCurrentTCB, %eax
|
||||
|
||||
/* Stack location is first item in the TCB. */
|
||||
movl %esp, (%eax)
|
||||
|
||||
call vTaskSwitchContext
|
||||
|
||||
/* Find the location of pxCurrentTCB again - a callee saved register could
|
||||
be used in place of eax to prevent this second load, but that then relies
|
||||
on the compiler and other asm code. */
|
||||
movl pxCurrentTCB, %eax
|
||||
|
||||
movl (%eax), %esp
|
||||
|
||||
.if configSUPPORT_FPU == 1
|
||||
|
||||
/* Restore address of task's FPU context buffer. */
|
||||
pop pucPortTaskFPUContextBuffer
|
||||
|
||||
/* If the task has a buffer allocated in which its FPU context is saved,
|
||||
then restore it now. */
|
||||
movl pucPortTaskFPUContextBuffer, %eax
|
||||
test %eax, %eax
|
||||
je 1f
|
||||
frstor ( %eax )
|
||||
1:
|
||||
.endif
|
||||
|
||||
popa
|
||||
iret
|
||||
|
||||
.endfunc
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
.align 4
|
||||
.func vPortStartFirstTask
|
||||
vPortStartFirstTask:
|
||||
|
||||
/* Find the TCB. */
|
||||
movl pxCurrentTCB, %eax
|
||||
|
||||
/* Stack location is first item in the TCB. */
|
||||
movl (%eax), %esp
|
||||
|
||||
/* Restore FPU context flag. */
|
||||
.if configSUPPORT_FPU == 1
|
||||
|
||||
pop pucPortTaskFPUContextBuffer
|
||||
|
||||
.endif /* configSUPPORT_FPU */
|
||||
|
||||
/* Restore general purpose registers. */
|
||||
popa
|
||||
movl $0x1, schedStart
|
||||
iret
|
||||
.endfunc
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
.align 4
|
||||
.func vPortAPICErrorHandlerWrapper
|
||||
vPortAPICErrorHandlerWrapper:
|
||||
pusha
|
||||
call vPortAPICErrorHandler
|
||||
popa
|
||||
/* EOI. */
|
||||
movl $0x00, (0xFEE000B0)
|
||||
iret
|
||||
.endfunc
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
.align 4
|
||||
.func vPortIRQHandler
|
||||
vPortIRQHandler:
|
||||
|
||||
/* Save general purpose registers. */
|
||||
pusha
|
||||
call send_char_to_cli
|
||||
mov $0x20, %eax
|
||||
mov $0x20, %edx
|
||||
outb %al, %dx
|
||||
popa
|
||||
|
||||
/* EOI. */
|
||||
movl $0x00, (0xFEE000B0)
|
||||
iret
|
||||
.endfunc
|
||||
|
||||
.align 4
|
||||
.func vHypervisorCallback
|
||||
vHypervisorCallback:
|
||||
|
||||
/* Save general purpose registers. */
|
||||
pusha
|
||||
call do_hypervisor_callback
|
||||
mov $0x20, %eax
|
||||
mov $0x20, %edx
|
||||
outb %al, %dx
|
||||
popa
|
||||
|
||||
/* EOI. */
|
||||
movl $0x00, (0xFEE000B0)
|
||||
iret
|
||||
.endfunc
|
||||
|
||||
.align 4
|
||||
.func vSCIHandler
|
||||
vSCIHandler:
|
||||
|
||||
/* Save general purpose registers. */
|
||||
pusha
|
||||
call process_sci
|
||||
mov $0x20, %eax
|
||||
mov $0x20, %edx
|
||||
outb %al, %dx
|
||||
popa
|
||||
|
||||
/* EOI. */
|
||||
movl $0x00, (0xFEE000B0)
|
||||
iret
|
||||
.endfunc
|
||||
|
||||
.align 4
|
||||
.func vTestInterruptHandler
|
||||
vTestInterruptHandler:
|
||||
|
||||
/* Save general purpose registers. */
|
||||
pusha
|
||||
call process_test_interrupt
|
||||
mov $0x20, %eax
|
||||
mov $0x20, %edx
|
||||
outb %al, %dx
|
||||
popa
|
||||
|
||||
/* EOI. */
|
||||
movl $0x00, (0xFEE000B0)
|
||||
iret
|
||||
.endfunc
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
.align 4
|
||||
.func vPortTimerHandler
|
||||
vPortTimerHandler:
|
||||
|
||||
/* Save general purpose registers. */
|
||||
pusha
|
||||
|
||||
movl schedStart, %eax
|
||||
test %eax, %eax
|
||||
je end_tmr
|
||||
/* Interrupts are not nested, so save the rest of the task context. */
|
||||
.if configSUPPORT_FPU == 1
|
||||
|
||||
/* If the task has a buffer allocated to save the FPU context then save the
|
||||
FPU context now. */
|
||||
movl pucPortTaskFPUContextBuffer, %eax
|
||||
test %eax, %eax
|
||||
je 1f
|
||||
fnsave ( %eax ) /* Save FLOP context into ucTempFPUBuffer array. */
|
||||
fwait
|
||||
|
||||
1:
|
||||
/* Save the address of the FPU context, if any. */
|
||||
push pucPortTaskFPUContextBuffer
|
||||
|
||||
.endif /* configSUPPORT_FPU */
|
||||
|
||||
/* Find the TCB. */
|
||||
movl pxCurrentTCB, %eax
|
||||
|
||||
/* Stack location is first item in the TCB. */
|
||||
movl %esp, (%eax)
|
||||
|
||||
/* Switch stacks. */
|
||||
movl ulTopOfSystemStack, %esp
|
||||
movl %esp, %ebp
|
||||
|
||||
/* Increment nesting count. */
|
||||
add $1, ulInterruptNesting
|
||||
|
||||
call xTaskIncrementTick
|
||||
|
||||
sti
|
||||
|
||||
/* Is a switch to another task required? */
|
||||
test %eax, %eax
|
||||
je _skip_context_switch
|
||||
cli
|
||||
call vTaskSwitchContext
|
||||
|
||||
_skip_context_switch:
|
||||
cli
|
||||
|
||||
/* Decrement the variable used to determine if a switch to a system
|
||||
stack is necessary. */
|
||||
sub $1, ulInterruptNesting
|
||||
|
||||
/* Stack location is first item in the TCB. */
|
||||
movl pxCurrentTCB, %eax
|
||||
movl (%eax), %esp
|
||||
|
||||
.if configSUPPORT_FPU == 1
|
||||
|
||||
/* Restore address of task's FPU context buffer. */
|
||||
pop pucPortTaskFPUContextBuffer
|
||||
|
||||
/* If the task has a buffer allocated in which its FPU context is saved,
|
||||
then restore it now. */
|
||||
movl pucPortTaskFPUContextBuffer, %eax
|
||||
test %eax, %eax
|
||||
je 1f
|
||||
frstor ( %eax )
|
||||
1:
|
||||
.endif
|
||||
|
||||
end_tmr:
|
||||
mov $0x20, %eax
|
||||
mov $0x20, %edx
|
||||
outb %al, %dx
|
||||
popa
|
||||
|
||||
/* EOI. */
|
||||
movl $0x00, (0xFEE000B0)
|
||||
iret
|
||||
|
||||
.endfunc
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
.if configUSE_COMMON_INTERRUPT_ENTRY_POINT == 1
|
||||
|
||||
.align 4
|
||||
.func vPortCentralInterruptWrapper
|
||||
vPortCentralInterruptWrapper:
|
||||
|
||||
portFREERTOS_INTERRUPT_ENTRY
|
||||
|
||||
movl $0xFEE00170, %eax /* Highest In Service Register (ISR) long word. */
|
||||
movl $8, %ecx /* Loop counter. */
|
||||
|
||||
next_isr_long_word:
|
||||
test %ecx, %ecx /* Loop counter reached 0? */
|
||||
je wrapper_epilogue /* Looked at all ISR registers without finding a bit set. */
|
||||
sub $1, %ecx /* Sub 1 from loop counter. */
|
||||
movl (%eax), %ebx /* Load next ISR long word. */
|
||||
sub $0x10, %eax /* Point to next ISR long word in case no bits are set in the current long word. */
|
||||
test %ebx, %ebx /* Are there any bits set? */
|
||||
je next_isr_long_word /* Look at next ISR long word if no bits were set. */
|
||||
sti
|
||||
bsr %ebx, %ebx /* A bit was set, which one? */
|
||||
movl $32, %eax /* Destination operand for following multiplication. */
|
||||
mul %ecx /* Calculate base vector for current register, 32 vectors per register. */
|
||||
add %ebx, %eax /* Add bit offset into register to get final vector number. */
|
||||
push %eax /* Vector number is function parameter. */
|
||||
call vPortCentralInterruptHandler
|
||||
pop %eax /* Remove parameter. */
|
||||
|
||||
wrapper_epilogue:
|
||||
portFREERTOS_INTERRUPT_EXIT
|
||||
|
||||
.endfunc
|
||||
|
||||
.endif /* configUSE_COMMON_INTERRUPT_ENTRY_POINT */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
.align 4
|
||||
.func vPortAPISpuriousHandler
|
||||
vPortAPICSpuriousHandler:
|
||||
iret
|
||||
|
||||
.endfunc
|
||||
|
||||
.end
|
||||
277
portable/GCC/XEN_x86/IA32/portmacro.h
Normal file
277
portable/GCC/XEN_x86/IA32/portmacro.h
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
/*
|
||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
#include "FreeRTOSConfig.h"
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||
* and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( ( TickType_t ) 0xffffffffUL )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 32
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task utilities. */
|
||||
|
||||
/* The interrupt priority (for vectors 16 to 255) is determined using vector/16.
|
||||
* The quotient is rounded to the nearest integer with 1 being the lowest priority
|
||||
* and 15 is the highest. Therefore the following two interrupts are at the lowest
|
||||
* priority. *NOTE 1* If the yield vector is changed then it must also be changed
|
||||
* in the portYIELD_INTERRUPT definition immediately below. */
|
||||
#define portAPIC_YIELD_INT_VECTOR ( 0x21 )
|
||||
#define portAPIC_TIMER_INT_VECTOR ( 0x22 )
|
||||
|
||||
/* Build yield interrupt instruction. */
|
||||
#define portYIELD_INTERRUPT "int $0x21"
|
||||
|
||||
/* APIC register addresses. */
|
||||
#define portAPIC_EOI ( *( ( volatile uint32_t * ) 0xFEE000B0UL ) )
|
||||
|
||||
/* APIC bit definitions. */
|
||||
#define portAPIC_ENABLE_BIT ( 1UL << 8UL )
|
||||
#define portAPIC_TIMER_PERIODIC ( 1UL << 17UL )
|
||||
#define portAPIC_DISABLE ( 1UL << 16UL )
|
||||
#define portAPIC_NMI ( 4 << 8 )
|
||||
#define portAPIC_DIV_16 ( 0x03 )
|
||||
|
||||
/* Define local API register addresses. */
|
||||
#define portAPIC_ID_REGISTER ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x20UL ) ) )
|
||||
#define portAPIC_SPURIOUS_INT ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xF0UL ) ) )
|
||||
#define portAPIC_LVT_TIMER ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x320UL ) ) )
|
||||
#define portAPIC_TIMER_INITIAL_COUNT ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x380UL ) ) )
|
||||
#define portAPIC_TIMER_CURRENT_COUNT ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x390UL ) ) )
|
||||
#define portAPIC_TASK_PRIORITY ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x80UL ) ) )
|
||||
#define portAPIC_LVT_ERROR ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x370UL ) ) )
|
||||
#define portAPIC_ERROR_STATUS ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x280UL ) ) )
|
||||
#define portAPIC_LDR ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xD0UL ) ) )
|
||||
#define portAPIC_TMRDIV ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x3E0UL ) ) )
|
||||
#define portAPIC_LVT_PERF ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x340UL ) ) )
|
||||
#define portAPIC_LVT_LINT0 ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x350UL ) ) )
|
||||
#define portAPIC_LVT_LINT1 ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x360UL ) ) )
|
||||
|
||||
extern int vHaltCPU(void);
|
||||
/* Don't yield if inside a critical section - instead hold the yield pending
|
||||
* so it is performed when the critical section is exited. */
|
||||
#define portYIELD() \
|
||||
{ \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
extern volatile uint32_t ulPortYieldPending; \
|
||||
if( ulCriticalNesting != 0 ) \
|
||||
{ \
|
||||
ulPortYieldPending = pdTRUE; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
__asm volatile ( portYIELD_INTERRUPT ); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Called at the end of an ISR that can cause a context switch - pend a yield if
|
||||
* xSwitchRequired is not false. */
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
{ \
|
||||
extern volatile uint32_t ulPortYieldPending; \
|
||||
if( xSwitchRequired != pdFALSE ) \
|
||||
{ \
|
||||
ulPortYieldPending = 1; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Same as portEND_SWITCHING_ISR() - take your pick which name to use. */
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Critical section control
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Critical sections for use in interrupts. */
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( x )
|
||||
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
extern uint32_t ulPortSetInterruptMask( void );
|
||||
extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
|
||||
|
||||
/* These macros do not globally disable/enable interrupts. They do mask off
|
||||
* interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
#define portDISABLE_INTERRUPTS() __asm volatile ( "cli" )
|
||||
#define portENABLE_INTERRUPTS() __asm volatile ( "sti" )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||
* not required for this port but included in case common demo code that uses these
|
||||
* macros is used. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
|
||||
/* Store/clear the ready priorities in a bit map. */
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) \
|
||||
__asm volatile ( "bsr %1, %0\n\t" \
|
||||
: "=r" ( uxTopPriority ) : "rm" ( uxReadyPriorities ) : "cc" )
|
||||
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
#define portNOP() __asm volatile ( "NOP" )
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Misc
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
#define portNUM_VECTORS 256
|
||||
#define portMAX_PRIORITY 15
|
||||
typedef void ( * ISR_Handler_t ) ( void );
|
||||
|
||||
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
|
||||
* before any floating point instructions are executed. */
|
||||
#ifndef configSUPPORT_FPU
|
||||
#define configSUPPORT_FPU 0
|
||||
#endif
|
||||
|
||||
#if configSUPPORT_FPU == 1
|
||||
void vPortTaskUsesFPU( void );
|
||||
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
||||
#endif
|
||||
|
||||
#ifndef configAPIC_BASE
|
||||
|
||||
/* configAPIC_BASE_ADDRESS sets the base address of the local APIC. It can
|
||||
* be overridden in FreeRTOSConfig.h should it not be constant. */
|
||||
#define configAPIC_BASE 0xFEE00000UL
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
|
||||
/* The FreeRTOS scheduling algorithm selects the task that will enter the
|
||||
* Running state. configUSE_PORT_OPTIMISED_TASK_SELECTION is used to set how
|
||||
* that is done.
|
||||
*
|
||||
* If configUSE_PORT_OPTIMISED_TASK_SELECTION is set to 0 then the task to
|
||||
* enter the Running state is selected using a portable algorithm written in
|
||||
* C. This is the slowest method, but the algorithm does not restrict the
|
||||
* maximum number of unique RTOS task priorities that are available.
|
||||
*
|
||||
* If configUSE_PORT_OPTIMISED_TASK_SELECTION is set to 1 then the task to
|
||||
* enter the Running state is selected using a single assembly instruction.
|
||||
* This is the fastest method, but restricts the maximum number of unique RTOS
|
||||
* task priorities to 32 (the same task priority can be assigned to any number
|
||||
* of RTOS tasks). */
|
||||
#warning configUSE_PORT_OPTIMISED_TASK_SELECTION was not defined in FreeRTOSConfig.h and has been defaulted to 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef configISR_STACK_SIZE
|
||||
|
||||
/* Interrupt entry code will switch the stack in use to a dedicated system
|
||||
* stack.
|
||||
*
|
||||
* configISR_STACK_SIZE defines the number of 32-bit values that can be stored
|
||||
* on the system stack, and must be large enough to hold a potentially nested
|
||||
* interrupt stack frame. */
|
||||
|
||||
#error configISR_STACK_SIZE was not defined in FreeRTOSConfig.h.
|
||||
#endif
|
||||
|
||||
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
||||
|
||||
/* Interrupt safe FreeRTOS functions (those that end in "FromISR" must not
|
||||
* be called from an interrupt that has a priority above that set by
|
||||
* configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||
#warning configMAX_API_CALL_INTERRUPT_PRIORITY was not defined in FreeRTOSConfig.h and has been defaulted to 10
|
||||
#define configMAX_API_CALL_INTERRUPT_PRIORITY 10
|
||||
#endif
|
||||
|
||||
#ifndef configSUPPORT_FPU
|
||||
#warning configSUPPORT_FPU was not defined in FreeRTOSConfig.h and has been defaulted to 0
|
||||
#define configSUPPORT_FPU 0
|
||||
#endif
|
||||
|
||||
/* The value written to the task priority register to raise the interrupt mask
|
||||
* to the maximum from which FreeRTOS API calls can be made. */
|
||||
#define portAPIC_PRIORITY_SHIFT ( 4UL )
|
||||
#define portAPIC_MAX_SUB_PRIORITY ( 0x0fUL )
|
||||
#define portMAX_API_CALL_PRIORITY ( ( configMAX_API_CALL_INTERRUPT_PRIORITY << portAPIC_PRIORITY_SHIFT ) | portAPIC_MAX_SUB_PRIORITY )
|
||||
|
||||
/* Asserts if interrupt safe FreeRTOS functions are called from a priority
|
||||
* above the max system call interrupt priority. */
|
||||
#define portAPIC_PROCESSOR_PRIORITY ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xA0UL ) ) )
|
||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( portAPIC_PROCESSOR_PRIORITY ) <= ( portMAX_API_CALL_PRIORITY ) )
|
||||
|
||||
/* Restricted User Mode Tasks Not Supported on 32-bit */
|
||||
#define portPRIVILEGE_BIT 0x0UL
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
257
portable/GCC/XEN_x86/IA32/startup.S
Normal file
257
portable/GCC/XEN_x86/IA32/startup.S
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
/*
|
||||
* FreeRTOS V202212.00
|
||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
/* Set to 1 to enable functionality */
|
||||
#define __SHOW_KERNEL_PARAMS__ 0
|
||||
|
||||
/* Local definitions boot loader */
|
||||
#define MULTIBOOT_SIGNATURE 0x2BADB002
|
||||
#define MULTIBOOT_BOOTINFO_MMAP 0x00000040
|
||||
|
||||
/* Local definitions for GD table */
|
||||
#define GDT_ENTRIES 8
|
||||
#define GDT_ENTRY_SIZE 8
|
||||
#define GDT_BYTES (GDT_ENTRIES * GDT_ENTRY_SIZE)
|
||||
|
||||
/* Globals and externs */
|
||||
.global _mboot_hdr
|
||||
.global _start
|
||||
.global _restart
|
||||
|
||||
.extern bootsign
|
||||
.extern bootinfo
|
||||
|
||||
.extern __text_start
|
||||
.extern __text_end
|
||||
.extern __data_vma
|
||||
.extern __data_lma
|
||||
.extern __data_start
|
||||
.extern __data_end
|
||||
.extern __bss_start
|
||||
.extern __bss_end
|
||||
.extern __stack_for_main
|
||||
|
||||
.global __text_start
|
||||
.global __text_end
|
||||
.global __data_vma
|
||||
.global __data_lma
|
||||
.global __data_start
|
||||
.global __data_end
|
||||
.global __bss_start
|
||||
.global __bss_end
|
||||
.globl shared_info, hypercall_page
|
||||
.global grant_table
|
||||
.global argo_ring
|
||||
.global rdtsc_low
|
||||
.global rdtsc_high
|
||||
|
||||
.extern setsegs
|
||||
.extern kernel_load_check
|
||||
.extern main
|
||||
.extern init_serial
|
||||
|
||||
/* Local constants for multiboot section */
|
||||
.set ALIGN, 1<<0 /* align loaded modules on page boundaries */
|
||||
.set MEMINFO, 1<<1 /* provide memory map */
|
||||
.set MAGIC, 0x1BADB002 /* 'magic number' lets bootloader find the header */
|
||||
.set FLAGS, ALIGN|MEMINFO /* this is the multiboot 'flag' field */
|
||||
.set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above */
|
||||
|
||||
/* Set-up GDT */
|
||||
.section .data
|
||||
|
||||
.align 16
|
||||
.globl gdt
|
||||
gdt: .space GDT_BYTES
|
||||
gdtr: .word (GDT_BYTES-1) /* sizeof _gdt -1 (in bytes) */
|
||||
.long gdt /* global pointer to the gdt */
|
||||
|
||||
/* Start of application text */
|
||||
.section .text.entry
|
||||
|
||||
/* Skip mb header */
|
||||
jmp _start
|
||||
|
||||
.align 4
|
||||
/* Multiboot header */
|
||||
_mboot_hdr:
|
||||
.long MAGIC /* offset = 0 */
|
||||
.long FLAGS /* offset = 4 */
|
||||
.long CHECKSUM /* offset = 8 */
|
||||
.long _mboot_hdr /* should be header address - offset = 12 */
|
||||
.long __text_start /* load address (start of text) - offset = 16 */
|
||||
.long __bss_start /* load end address (end of data) - offset = 20*/
|
||||
.long __bss_end /* bss end address - offset = 24*/
|
||||
.long _start /* entry_addr - offset = 28*/
|
||||
|
||||
#define ELFNOTE(name, type, desc) \
|
||||
.pushsection .note.name ; \
|
||||
.align 4 ; \
|
||||
.long 2f - 1f /* namesz */ ; \
|
||||
.long 4f - 3f /* descsz */ ; \
|
||||
.long type /* type */ ; \
|
||||
1:.asciz #name /* name */ ; \
|
||||
2:.align 4 ; \
|
||||
3:desc /* desc */ ; \
|
||||
4:.align 4 ; \
|
||||
.popsection
|
||||
|
||||
#define XEN_ELFNOTE_PHYS32_ENTRY 18
|
||||
ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY, .long _start)
|
||||
|
||||
/* Unpleasant -- the PTE that maps this page is actually overwritten */
|
||||
/* to map the real shared-info page! :-) */
|
||||
.align 4096
|
||||
shared_info:
|
||||
.fill 4096,1,0
|
||||
|
||||
hypercall_page:
|
||||
.fill 4096,1,0
|
||||
grant_table:
|
||||
.fill 4096*2,1,0
|
||||
argo_ring:
|
||||
.fill 4096*5,1,0
|
||||
rdtsc_low:
|
||||
.fill 4,1,0
|
||||
rdtsc_high:
|
||||
.fill 4,1,0
|
||||
|
||||
|
||||
/* Start of executable code */
|
||||
_start:
|
||||
|
||||
_restart:
|
||||
|
||||
/* Initialise the stack pointer */
|
||||
movl $__stack_for_main, %esp
|
||||
|
||||
/* Reset EFLAGS. */
|
||||
pushl $0
|
||||
popf
|
||||
|
||||
rdtsc # Reads TSC -> %edx:%eax
|
||||
movl %eax, rdtsc_low # Store lower 32 bits
|
||||
movl %edx, rdtsc_high # Store upper 32 bits
|
||||
/* Set up the global descriptor table */
|
||||
call setsegs
|
||||
lgdt gdtr
|
||||
ljmp $0x8, $gdt1 /* CS descriptor 1 */
|
||||
gdt1:
|
||||
movl $0x10, %eax /* DS descriptor 2 */
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
movl $0x18, %eax /* SS descriptor 3 */
|
||||
movw %ax, %ss
|
||||
|
||||
/* Clear interrupt flag */
|
||||
cli
|
||||
|
||||
/* Initialise platform */
|
||||
|
||||
/* Show kernel parameters and call main, or just call main */
|
||||
#if (__SHOW_KERNEL_PARAMS__ == 1)
|
||||
/*---------------------------------------------------------------------
|
||||
On successful OS load EAX should contain 0x2BADB002
|
||||
EBX should contain the physical address of multiboot info structure
|
||||
|
||||
Push the pointers to the multiboot information structure
|
||||
and the magic number on the stack and check values returned
|
||||
----------------------------------------------------------------------*/
|
||||
movl bootsign, %eax
|
||||
movl bootinfo, %ebx
|
||||
pushl %ebx /* Multiboot information */
|
||||
pushl %eax /* Magic number */
|
||||
call show_kernel_parameters
|
||||
#else
|
||||
/*---------------------------------------------------------------------
|
||||
Call main() routine
|
||||
----------------------------------------------------------------------*/
|
||||
call init_serial
|
||||
pushl %ebx /* Multiboot information */
|
||||
call main
|
||||
#endif
|
||||
|
||||
/* Should not get here, but just in case - loop forever */
|
||||
cli
|
||||
_local_loop:
|
||||
hlt
|
||||
jmp _local_loop
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
GLOBAL ASSEMBLY LANGUAGE ROUTINES
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
/* halt */
|
||||
.globl halt
|
||||
halt:
|
||||
jmp halt
|
||||
ret
|
||||
|
||||
/* inb */
|
||||
.globl inb
|
||||
inb: movl 4(%esp), %edx
|
||||
xorl %eax, %eax # clr eax
|
||||
inb %dx, %al
|
||||
ret
|
||||
|
||||
/* inw */
|
||||
.globl inw
|
||||
inw: movl 4(%esp), %edx
|
||||
xorl %eax, %eax # clr eax
|
||||
inw %dx, %ax
|
||||
ret
|
||||
|
||||
/* inl */
|
||||
.globl inl
|
||||
inl: movl 4(%esp), %edx
|
||||
xorl %eax, %eax
|
||||
inl %dx, %eax
|
||||
ret
|
||||
|
||||
/* outb */
|
||||
.globl outb
|
||||
outb: movl 4(%esp), %edx
|
||||
movl 8(%esp), %eax
|
||||
outb %al, %dx
|
||||
ret
|
||||
|
||||
/* outw */
|
||||
.globl outw
|
||||
outw: movl 4(%esp), %edx
|
||||
movl 8(%esp), %eax
|
||||
outw %ax, %dx
|
||||
ret
|
||||
|
||||
/* outl */
|
||||
.globl outl
|
||||
outl: movl 4(%esp), %edx
|
||||
movl 8(%esp), %eax
|
||||
outl %eax, %dx
|
||||
ret
|
||||
|
||||
.end
|
||||
53
portable/GCC/XEN_x86/x86-64/asm_src/header.asm
Normal file
53
portable/GCC/XEN_x86/x86-64/asm_src/header.asm
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
; header
|
||||
;
|
||||
; Copyright (C) 2025 Advanced Micro Devices, Inc. or its affiliates. All Rights Reserved.
|
||||
;
|
||||
; SPDX-License-Identifier: MIT
|
||||
;
|
||||
; Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
; this software and associated documentation files (the "Software"), to deal in
|
||||
; the Software without restriction, including without limitation the rights to
|
||||
; use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
; the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
; subject to the following conditions:
|
||||
;
|
||||
; The above copyright notice and this permission notice shall be included in all
|
||||
; copies or substantial portions of the Software.
|
||||
;
|
||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
; FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
; COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
; IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
;
|
||||
|
||||
MB2_ARCH EQU 0 ; 0 = x86/x86-64
|
||||
MB2_LEN EQU (mbend-mbhead)
|
||||
MB2_MAGIC EQU 0xe85250d6
|
||||
|
||||
section .multiboot_header align=4096
|
||||
mbhead:
|
||||
dd MB2_MAGIC ; Multiboot2 magic number
|
||||
dd MB2_ARCH ; Architecture
|
||||
dd MB2_LEN ; Multiboot header length
|
||||
dd 0x100000000 - MB2_LEN - MB2_ARCH - MB2_MAGIC
|
||||
; Checksum
|
||||
|
||||
mb2_tag_info_start:
|
||||
dw 1 ; multiboot information request
|
||||
dw 0
|
||||
dd mb2_tag_info_end - mb2_tag_info_start
|
||||
dd 1
|
||||
dd 2
|
||||
dd 6
|
||||
mb2_tag_info_end:
|
||||
|
||||
align 8
|
||||
mb2_tag_end_start:
|
||||
dw 0 ; last tag
|
||||
dw 0
|
||||
dd mb2_tag_end_end - mb2_tag_end_start
|
||||
mb2_tag_end_end:
|
||||
|
||||
mbend:
|
||||
367
portable/GCC/XEN_x86/x86-64/asm_src/idt.asm
Normal file
367
portable/GCC/XEN_x86/x86-64/asm_src/idt.asm
Normal file
|
|
@ -0,0 +1,367 @@
|
|||
; idt
|
||||
;
|
||||
; Copyright (C) 2025 Advanced Micro Devices, Inc. or its affiliates. All Rights Reserved.
|
||||
;
|
||||
; SPDX-License-Identifier: MIT
|
||||
;
|
||||
; Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
; this software and associated documentation files (the "Software"), to deal in
|
||||
; the Software without restriction, including without limitation the rights to
|
||||
; use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
; the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
; subject to the following conditions:
|
||||
;
|
||||
; The above copyright notice and this permission notice shall be included in all
|
||||
; copies or substantial portions of the Software.
|
||||
;
|
||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
; FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
; COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
; IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
;
|
||||
|
||||
section .text
|
||||
extern vHandler
|
||||
global sysint
|
||||
global read_isr
|
||||
global load_idt
|
||||
global load_cr3
|
||||
global starttask
|
||||
global read_cr2
|
||||
global InterruptReturn
|
||||
|
||||
Interrupt:
|
||||
push rax
|
||||
push rbx
|
||||
push rcx
|
||||
push rdx
|
||||
push rsi
|
||||
push rdi
|
||||
push rbp
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
|
||||
mov rdi,rsp
|
||||
call vHandler
|
||||
|
||||
InterruptReturn:
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
pop r12
|
||||
pop r11
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
pop rbp
|
||||
pop rdi
|
||||
pop rsi
|
||||
pop rdx
|
||||
pop rcx
|
||||
pop rbx
|
||||
pop rax
|
||||
|
||||
add rsp,16
|
||||
iretq
|
||||
|
||||
%macro VECTOR_1 1
|
||||
global vector%1
|
||||
vector%1:
|
||||
cli
|
||||
push byte %1
|
||||
jmp Interrupt
|
||||
%endmacro
|
||||
|
||||
%macro VECTOR_2 1
|
||||
global vector%1
|
||||
vector%1:
|
||||
cli
|
||||
push 0
|
||||
push %1
|
||||
jmp Interrupt
|
||||
%endmacro
|
||||
|
||||
|
||||
VECTOR_2 0
|
||||
VECTOR_2 1
|
||||
VECTOR_2 2
|
||||
VECTOR_2 3
|
||||
VECTOR_2 4
|
||||
VECTOR_2 5
|
||||
VECTOR_2 6
|
||||
VECTOR_2 7
|
||||
|
||||
; Error code is pushed by CPU for the following vectors
|
||||
; So we dont push error code in these vectors
|
||||
VECTOR_1 8
|
||||
VECTOR_1 10
|
||||
VECTOR_1 11
|
||||
VECTOR_1 12
|
||||
VECTOR_1 13
|
||||
VECTOR_1 14
|
||||
|
||||
VECTOR_2 16
|
||||
VECTOR_1 17
|
||||
VECTOR_2 18
|
||||
VECTOR_2 19
|
||||
VECTOR_2 32
|
||||
VECTOR_2 33
|
||||
VECTOR_2 34
|
||||
VECTOR_2 35
|
||||
VECTOR_2 36
|
||||
VECTOR_2 37
|
||||
VECTOR_2 38
|
||||
VECTOR_2 39
|
||||
VECTOR_2 40
|
||||
VECTOR_2 41
|
||||
VECTOR_2 42
|
||||
VECTOR_2 43
|
||||
VECTOR_2 44
|
||||
VECTOR_2 45
|
||||
VECTOR_2 46
|
||||
VECTOR_2 47
|
||||
VECTOR_2 48
|
||||
VECTOR_2 49
|
||||
VECTOR_2 50
|
||||
VECTOR_2 51
|
||||
VECTOR_2 52
|
||||
VECTOR_2 53
|
||||
VECTOR_2 54
|
||||
VECTOR_2 55
|
||||
VECTOR_2 56
|
||||
VECTOR_2 57
|
||||
VECTOR_2 58
|
||||
VECTOR_2 59
|
||||
VECTOR_2 60
|
||||
VECTOR_2 61
|
||||
VECTOR_2 62
|
||||
VECTOR_2 63
|
||||
VECTOR_2 64
|
||||
VECTOR_2 65
|
||||
VECTOR_2 66
|
||||
VECTOR_2 67
|
||||
VECTOR_2 68
|
||||
VECTOR_2 69
|
||||
VECTOR_2 70
|
||||
VECTOR_2 71
|
||||
VECTOR_2 72
|
||||
VECTOR_2 73
|
||||
VECTOR_2 74
|
||||
VECTOR_2 75
|
||||
VECTOR_2 76
|
||||
VECTOR_2 77
|
||||
VECTOR_2 78
|
||||
VECTOR_2 79
|
||||
VECTOR_2 80
|
||||
VECTOR_2 81
|
||||
VECTOR_2 82
|
||||
VECTOR_2 83
|
||||
VECTOR_2 84
|
||||
VECTOR_2 85
|
||||
VECTOR_2 86
|
||||
VECTOR_2 87
|
||||
VECTOR_2 88
|
||||
VECTOR_2 89
|
||||
VECTOR_2 90
|
||||
VECTOR_2 91
|
||||
VECTOR_2 92
|
||||
VECTOR_2 93
|
||||
VECTOR_2 94
|
||||
VECTOR_2 95
|
||||
VECTOR_2 96
|
||||
VECTOR_2 97
|
||||
VECTOR_2 98
|
||||
VECTOR_2 99
|
||||
VECTOR_2 100
|
||||
VECTOR_2 101
|
||||
VECTOR_2 102
|
||||
VECTOR_2 103
|
||||
VECTOR_2 104
|
||||
VECTOR_2 105
|
||||
VECTOR_2 106
|
||||
VECTOR_2 107
|
||||
VECTOR_2 108
|
||||
VECTOR_2 109
|
||||
VECTOR_2 110
|
||||
VECTOR_2 111
|
||||
VECTOR_2 112
|
||||
VECTOR_2 113
|
||||
VECTOR_2 114
|
||||
VECTOR_2 115
|
||||
VECTOR_2 116
|
||||
VECTOR_2 117
|
||||
VECTOR_2 118
|
||||
VECTOR_2 119
|
||||
VECTOR_2 120
|
||||
VECTOR_2 121
|
||||
VECTOR_2 122
|
||||
VECTOR_2 123
|
||||
VECTOR_2 124
|
||||
VECTOR_2 125
|
||||
VECTOR_2 126
|
||||
VECTOR_2 127
|
||||
; 128 is used by system calls
|
||||
VECTOR_2 129
|
||||
VECTOR_2 130
|
||||
VECTOR_2 131
|
||||
VECTOR_2 132
|
||||
VECTOR_2 133
|
||||
VECTOR_2 134
|
||||
VECTOR_2 135
|
||||
VECTOR_2 136
|
||||
VECTOR_2 137
|
||||
VECTOR_2 138
|
||||
VECTOR_2 139
|
||||
VECTOR_2 140
|
||||
VECTOR_2 141
|
||||
VECTOR_2 142
|
||||
VECTOR_2 143
|
||||
VECTOR_2 144
|
||||
VECTOR_2 145
|
||||
VECTOR_2 146
|
||||
VECTOR_2 147
|
||||
VECTOR_2 148
|
||||
VECTOR_2 149
|
||||
VECTOR_2 150
|
||||
VECTOR_2 151
|
||||
VECTOR_2 152
|
||||
VECTOR_2 153
|
||||
VECTOR_2 154
|
||||
VECTOR_2 155
|
||||
VECTOR_2 156
|
||||
VECTOR_2 157
|
||||
VECTOR_2 158
|
||||
VECTOR_2 159
|
||||
VECTOR_2 160
|
||||
VECTOR_2 161
|
||||
VECTOR_2 162
|
||||
VECTOR_2 163
|
||||
VECTOR_2 164
|
||||
VECTOR_2 165
|
||||
VECTOR_2 166
|
||||
VECTOR_2 167
|
||||
VECTOR_2 168
|
||||
VECTOR_2 169
|
||||
VECTOR_2 170
|
||||
VECTOR_2 171
|
||||
VECTOR_2 172
|
||||
VECTOR_2 173
|
||||
VECTOR_2 174
|
||||
VECTOR_2 175
|
||||
VECTOR_2 176
|
||||
VECTOR_2 177
|
||||
VECTOR_2 178
|
||||
VECTOR_2 179
|
||||
VECTOR_2 180
|
||||
VECTOR_2 181
|
||||
VECTOR_2 182
|
||||
VECTOR_2 183
|
||||
VECTOR_2 184
|
||||
VECTOR_2 185
|
||||
VECTOR_2 186
|
||||
VECTOR_2 187
|
||||
VECTOR_2 188
|
||||
VECTOR_2 189
|
||||
VECTOR_2 190
|
||||
VECTOR_2 191
|
||||
VECTOR_2 192
|
||||
VECTOR_2 193
|
||||
VECTOR_2 194
|
||||
VECTOR_2 195
|
||||
VECTOR_2 196
|
||||
VECTOR_2 197
|
||||
VECTOR_2 198
|
||||
VECTOR_2 199
|
||||
VECTOR_2 200
|
||||
VECTOR_2 201
|
||||
VECTOR_2 202
|
||||
VECTOR_2 203
|
||||
VECTOR_2 204
|
||||
VECTOR_2 205
|
||||
VECTOR_2 206
|
||||
VECTOR_2 207
|
||||
VECTOR_2 208
|
||||
VECTOR_2 209
|
||||
VECTOR_2 210
|
||||
VECTOR_2 211
|
||||
VECTOR_2 212
|
||||
VECTOR_2 213
|
||||
VECTOR_2 214
|
||||
VECTOR_2 215
|
||||
VECTOR_2 216
|
||||
VECTOR_2 217
|
||||
VECTOR_2 218
|
||||
VECTOR_2 219
|
||||
VECTOR_2 220
|
||||
VECTOR_2 221
|
||||
VECTOR_2 222
|
||||
VECTOR_2 223
|
||||
VECTOR_2 224
|
||||
VECTOR_2 225
|
||||
VECTOR_2 226
|
||||
VECTOR_2 227
|
||||
VECTOR_2 228
|
||||
VECTOR_2 229
|
||||
VECTOR_2 230
|
||||
VECTOR_2 231
|
||||
VECTOR_2 232
|
||||
VECTOR_2 233
|
||||
VECTOR_2 234
|
||||
VECTOR_2 235
|
||||
VECTOR_2 236
|
||||
VECTOR_2 237
|
||||
VECTOR_2 238
|
||||
VECTOR_2 239
|
||||
VECTOR_2 240
|
||||
VECTOR_2 241
|
||||
VECTOR_2 242
|
||||
VECTOR_2 243
|
||||
VECTOR_2 244
|
||||
VECTOR_2 245
|
||||
VECTOR_2 246
|
||||
VECTOR_2 247
|
||||
VECTOR_2 248
|
||||
VECTOR_2 249
|
||||
VECTOR_2 250
|
||||
VECTOR_2 251
|
||||
VECTOR_2 252
|
||||
VECTOR_2 253
|
||||
VECTOR_2 254
|
||||
VECTOR_2 255
|
||||
|
||||
sysint:
|
||||
push 0
|
||||
push 0x80
|
||||
jmp Interrupt
|
||||
|
||||
read_isr:
|
||||
mov al,11
|
||||
out 0x20,al
|
||||
in al,0x20
|
||||
ret
|
||||
|
||||
load_idt:
|
||||
lidt [rdi]
|
||||
ret
|
||||
|
||||
load_cr3:
|
||||
mov rax,rdi
|
||||
mov cr3,rax
|
||||
ret
|
||||
|
||||
read_cr2:
|
||||
mov rax,cr2
|
||||
ret
|
||||
|
||||
starttask:
|
||||
mov rsp,rdi
|
||||
jmp InterruptReturn
|
||||
|
||||
240
portable/GCC/XEN_x86/x86-64/asm_src/main.asm
Normal file
240
portable/GCC/XEN_x86/x86-64/asm_src/main.asm
Normal file
|
|
@ -0,0 +1,240 @@
|
|||
; main
|
||||
;
|
||||
; Copyright (C) 2025 Advanced Micro Devices, Inc. or its affiliates. All Rights Reserved.
|
||||
;
|
||||
; SPDX-License-Identifier: MIT
|
||||
;
|
||||
; Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
; this software and associated documentation files (the "Software"), to deal in
|
||||
; the Software without restriction, including without limitation the rights to
|
||||
; use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
; the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
; subject to the following conditions:
|
||||
;
|
||||
; The above copyright notice and this permission notice shall be included in all
|
||||
; copies or substantial portions of the Software.
|
||||
;
|
||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
; FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
; COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
; IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
;
|
||||
|
||||
global start
|
||||
global mboot_info
|
||||
global pml4
|
||||
global pud
|
||||
global wakeup
|
||||
global hypercall_page
|
||||
global shared_info
|
||||
extern long_mode_start
|
||||
global grant_table
|
||||
global argo_ring
|
||||
global rdtsc_low
|
||||
global rdtsc_high
|
||||
|
||||
section .text
|
||||
bits 32
|
||||
start:
|
||||
mov esp, stack_top
|
||||
rdtsc
|
||||
mov [rdtsc_low], eax
|
||||
mov [rdtsc_high], edx
|
||||
mov [mboot_info], ebx
|
||||
call setup_page_tables
|
||||
call enable_paging
|
||||
|
||||
lgdt [Gdt64KernelPtr]
|
||||
jmp 8:long_mode_start
|
||||
|
||||
hlt
|
||||
|
||||
setup_page_tables:
|
||||
lea eax, [pud] ; Load the address of pud into eax
|
||||
mov edx, 0x0 ; Upper 32-bits of the address (since we're in 32-bit mode, this is 0)
|
||||
or eax, 0x3 ; OR the lower 32-bits of the address with 0x3
|
||||
mov [pml4], eax ; Store the lower 32-bits in pml4[0] (low)
|
||||
mov [pml4+4], edx ; Store the upper 32-bits in pml4[0] (high, which is 0)
|
||||
|
||||
; Set pud[0] = 0x0000000083 (64-bit value, split into two 32-bit parts)
|
||||
mov eax, 0x83 ; Load the lower 32-bits of 0x0000000083 into eax
|
||||
mov edx, 0x0 ; Upper 32-bits of the value (0x00000000)
|
||||
mov [pud], eax ; Store the lower 32-bits in pud[0] (low)
|
||||
mov [pud+4], edx ; Store the upper 32-bits in pud[0] (high)
|
||||
ret
|
||||
|
||||
|
||||
enable_paging:
|
||||
; pass page table location to cpu
|
||||
mov eax, pml4
|
||||
mov cr3, eax
|
||||
|
||||
; enable PAE
|
||||
mov eax, cr4
|
||||
or eax, 1 << 5
|
||||
mov cr4, eax
|
||||
|
||||
; enable long mode
|
||||
mov ecx, 0xC0000080
|
||||
rdmsr
|
||||
or eax, 1 << 8
|
||||
wrmsr
|
||||
|
||||
; enable paging
|
||||
mov eax, cr0
|
||||
or eax, 1 << 31
|
||||
mov cr0, eax
|
||||
mov eax, cr0
|
||||
|
||||
ret
|
||||
|
||||
section .bss
|
||||
align 4096
|
||||
hypercall_page:
|
||||
resb 4096
|
||||
shared_info:
|
||||
resb 4096
|
||||
grant_table:
|
||||
resb 4096 * 2
|
||||
argo_ring:
|
||||
resb 4096 * 5
|
||||
|
||||
section .bss
|
||||
align 4096
|
||||
pml4:
|
||||
resb 4096
|
||||
pud:
|
||||
resb 4096*512
|
||||
stack_bottom:
|
||||
resb 16384 * 4
|
||||
stack_top:
|
||||
|
||||
section .rodata
|
||||
Gdt64Kernel:
|
||||
dq 0
|
||||
dq 0x0020980000000000
|
||||
|
||||
Gdt64KernelLen: equ $-Gdt64Kernel
|
||||
|
||||
Gdt64KernelPtr: dw Gdt64KernelLen-1
|
||||
dd Gdt64Kernel
|
||||
|
||||
extern main
|
||||
extern serial_send
|
||||
extern init_serial
|
||||
extern mboot_info
|
||||
|
||||
section .data
|
||||
mboot_info:
|
||||
dd 0
|
||||
rdtsc_low:
|
||||
dd 0
|
||||
rdtsc_high:
|
||||
dd 0
|
||||
global Tss
|
||||
|
||||
Gdt64:
|
||||
dq 0
|
||||
dq 0x0020980000000000
|
||||
dq 0x0020920000000000
|
||||
dq 0x0020f80000000000
|
||||
dq 0x0000f20000000000
|
||||
|
||||
TssDesc:
|
||||
dw TssLen-1
|
||||
dw 0
|
||||
db 0
|
||||
db 0x89
|
||||
db 0
|
||||
db 0
|
||||
dq 0
|
||||
|
||||
Gdt64Len: equ $-Gdt64
|
||||
|
||||
Gdt64Ptr: dw Gdt64Len-1
|
||||
dq Gdt64
|
||||
|
||||
Tss:
|
||||
dd 0
|
||||
dq 0xffff800000190000
|
||||
times 88 db 0
|
||||
dd TssLen
|
||||
|
||||
TssLen: equ $-Tss
|
||||
|
||||
section .text
|
||||
bits 64
|
||||
long_mode_start:
|
||||
|
||||
; Load 64-bit GDT Descriptor in Global Descriptor Table Register
|
||||
mov rax,Gdt64Ptr
|
||||
lgdt [rax]
|
||||
|
||||
; Load TSS address into Tss Descriptor
|
||||
mov rax,Tss
|
||||
mov rdi,TssDesc
|
||||
mov [rdi+2],ax
|
||||
shr rax,16
|
||||
mov [rdi+4],al
|
||||
shr rax,8
|
||||
mov [rdi+7],al
|
||||
shr rax,8
|
||||
mov [rdi+8],eax
|
||||
mov ax,0x28
|
||||
|
||||
; activate Tss
|
||||
ltr ax
|
||||
|
||||
; enable SSE instructions
|
||||
mov rax, cr0
|
||||
bts rax, 1
|
||||
btr rax, 2
|
||||
mov cr0, rax
|
||||
mov rax, cr4
|
||||
bts rax, 9
|
||||
bts rax, 10
|
||||
mov cr4, rax
|
||||
finit
|
||||
|
||||
; enable avx if available
|
||||
mov eax, 1
|
||||
cpuid
|
||||
bt ecx, 28
|
||||
|
||||
jnc avx_not_supported
|
||||
avx_supported:
|
||||
mov rax, cr4
|
||||
bts rax, 18
|
||||
mov cr4, rax
|
||||
xor ecx, ecx
|
||||
xgetbv
|
||||
bts rax, 0
|
||||
bts rax, 1
|
||||
bts rax, 2
|
||||
xsetbv
|
||||
avx_not_supported:
|
||||
|
||||
; load null into all data segment registers
|
||||
mov ax, 0x10
|
||||
mov ss, ax
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
call init_serial
|
||||
cmp word[mboot_info], 0
|
||||
je err
|
||||
; load mboot_info in parameter (rdi)
|
||||
; and call main
|
||||
mov rdi, 0
|
||||
mov edi, [mboot_info]
|
||||
call main
|
||||
|
||||
hlt
|
||||
|
||||
err:
|
||||
hlt
|
||||
jmp err
|
||||
298
portable/GCC/XEN_x86/x86-64/asm_src/syscall.asm
Normal file
298
portable/GCC/XEN_x86/x86-64/asm_src/syscall.asm
Normal file
|
|
@ -0,0 +1,298 @@
|
|||
; syscall
|
||||
;
|
||||
; Copyright (C) 2025 Advanced Micro Devices, Inc. or its affiliates. All Rights Reserved.
|
||||
;
|
||||
; SPDX-License-Identifier: MIT
|
||||
;
|
||||
; Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
; this software and associated documentation files (the "Software"), to deal in
|
||||
; the Software without restriction, including without limitation the rights to
|
||||
; use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
; the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
; subject to the following conditions:
|
||||
;
|
||||
; The above copyright notice and this permission notice shall be included in all
|
||||
; copies or substantial portions of the Software.
|
||||
;
|
||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
; FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
; COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
; IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
;
|
||||
|
||||
section freertos_system_calls
|
||||
%define SYSCALL_NUM_writec 0
|
||||
%define SYSCALL_NUM_xTaskGetTickCount 1
|
||||
%define SYSCALL_NUM_xTaskDelayUntil 2
|
||||
%define SYSCALL_NUM_xQueueGenericSend 3
|
||||
%define SYSCALL_NUM_xQueueReceive 4
|
||||
%define SYSCALL_NUM_xTimerGenericCommandFromTask 5
|
||||
%define SYSCALL_NUM_eTaskGetState 6
|
||||
%define SYSCALL_NUM_pcQueueGetName 7
|
||||
%define SYSCALL_NUM_pcTimerGetName 8
|
||||
%define SYSCALL_NUM_pvTimerGetTimerID 9
|
||||
%define SYSCALL_NUM_ulTaskGenericNotifyTake 10
|
||||
%define SYSCALL_NUM_ulTaskGenericNotifyValueClear 11
|
||||
%define SYSCALL_NUM_uxQueueMessagesWaiting 12
|
||||
%define SYSCALL_NUM_uxQueueSpacesAvailable 13
|
||||
%define SYSCALL_NUM_uxTaskGetNumberOfTasks 14
|
||||
%define SYSCALL_NUM_uxTaskGetSystemState 15
|
||||
%define SYSCALL_NUM_uxTaskPriorityGet 16
|
||||
%define SYSCALL_NUM_uxTimerGetReloadMode 17
|
||||
%define SYSCALL_NUM_vQueueAddToRegistry 18
|
||||
%define SYSCALL_NUM_vQueueUnregisterQueue 19
|
||||
%define SYSCALL_NUM_vTaskDelay 20
|
||||
%define SYSCALL_NUM_vTaskGetInfo 21
|
||||
%define SYSCALL_NUM_vTaskResume 22
|
||||
%define SYSCALL_NUM_vTaskSetTimeOutState 23
|
||||
%define SYSCALL_NUM_vTaskSuspend 24
|
||||
%define SYSCALL_NUM_vTaskSuspendAll 25
|
||||
%define SYSCALL_NUM_vTimerSetReloadMode 26
|
||||
%define SYSCALL_NUM_vTimerSetTimerID 27
|
||||
%define SYSCALL_NUM_xQueueAddToSet 28
|
||||
%define SYSCALL_NUM_xQueueGiveMutexRecursive 29
|
||||
%define SYSCALL_NUM_xQueuePeek 30
|
||||
%define SYSCALL_NUM_xQueueRemoveFromSet 31
|
||||
%define SYSCALL_NUM_xQueueSelectFromSet 32
|
||||
%define SYSCALL_NUM_xQueueSemaphoreTake 33
|
||||
%define SYSCALL_NUM_xQueueTakeMutexRecursive 34
|
||||
%define SYSCALL_NUM_xTaskCheckForTimeOut 35
|
||||
%define SYSCALL_NUM_xTaskGenericNotify 36
|
||||
%define SYSCALL_NUM_xTaskGenericNotifyStateClear 37
|
||||
%define SYSCALL_NUM_xTaskGenericNotifyWait 38
|
||||
%define SYSCALL_NUM_xTaskGetCurrentTaskHandle 39
|
||||
%define SYSCALL_NUM_xTaskGetSchedulerState 40
|
||||
%define SYSCALL_NUM_xTimerGetExpiryTime 41
|
||||
%define SYSCALL_NUM_xTimerGetPeriod 42
|
||||
%define SYSCALL_NUM_xTimerGetTimerDaemonTaskHandle 43
|
||||
%define SYSCALL_NUM_xTimerIsTimerActive 44
|
||||
%define SYSCALL_NUM_xTaskAbortDelay 45
|
||||
%define SYSCALL_NUM_xTaskGetHandle 46
|
||||
%define SYSCALL_NUM_xEventGroupCreate 47
|
||||
%define SYSCALL_NUM_xEventGroupWaitBits 48
|
||||
%define SYSCALL_NUM_vEventGroupDelete 49
|
||||
%define SYSCALL_NUM_xStreamBufferGenericCreate 50
|
||||
%define SYSCALL_NUM_xStreamBufferReceive 51
|
||||
%define SYSCALL_NUM_vStreamBufferDelete 52
|
||||
%define SYSCALL_NUM_xQueueGetMutexHolder 53
|
||||
%define SYSCALL_NUM_xEventGroupSync 54
|
||||
%define SYSCALL_NUM_xEventGroupSetBits 55
|
||||
%define SYSCALL_NUM_xEventGroupClearBits 56
|
||||
%define SYSCALL_NUM_xStreamBufferSend 57
|
||||
%define SYSCALL_NUM_xStreamBufferIsEmpty 58
|
||||
%define SYSCALL_NUM_xStreamBufferNextMessageLengthBytes 59
|
||||
%define SYSCALL_NUM_xStreamBufferIsFull 60
|
||||
%define SYSCALL_NUM_xStreamBufferSpacesAvailable 61
|
||||
%define SYSCALL_NUM_xStreamBufferReset 62
|
||||
%define SYSCALL_NUM_xStreamBufferBytesAvailable 64
|
||||
|
||||
|
||||
%macro SYSCALL_0 2
|
||||
global %1
|
||||
%1:
|
||||
mov eax,%2
|
||||
mov rdi,0
|
||||
mov rsi,rsp
|
||||
int 0x80
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro SYSCALL_1 2
|
||||
global %1
|
||||
%1:
|
||||
sub rsp,8
|
||||
mov eax, %2
|
||||
|
||||
mov [rsp],rdi
|
||||
|
||||
mov rdi,1
|
||||
mov rsi,rsp
|
||||
int 0x80
|
||||
|
||||
add rsp,8
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro SYSCALL_2 2
|
||||
global %1
|
||||
%1:
|
||||
sub rsp,16
|
||||
mov eax, %2
|
||||
|
||||
mov [rsp],rdi
|
||||
mov [rsp+8],rsi
|
||||
|
||||
mov rdi,2
|
||||
mov rsi,rsp
|
||||
int 0x80
|
||||
|
||||
add rsp,16
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro SYSCALL_3 2
|
||||
global %1
|
||||
%1:
|
||||
sub rsp,24
|
||||
mov eax, %2
|
||||
|
||||
mov [rsp],rdi
|
||||
mov [rsp+8],rsi
|
||||
mov [rsp+16],rdx
|
||||
|
||||
mov rdi,3
|
||||
mov rsi,rsp
|
||||
int 0x80
|
||||
|
||||
add rsp,24
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro SYSCALL_4 2
|
||||
global %1
|
||||
%1:
|
||||
sub rsp, 32
|
||||
mov eax, %2
|
||||
|
||||
mov [rsp],rdi
|
||||
mov [rsp+8],rsi
|
||||
mov [rsp+16],rdx
|
||||
mov [rsp+24],rcx
|
||||
|
||||
mov rdi,4
|
||||
mov rsi,rsp
|
||||
int 0x80
|
||||
|
||||
add rsp,32
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro SYSCALL_5 2
|
||||
global %1
|
||||
%1:
|
||||
sub rsp, 40
|
||||
mov eax, %2
|
||||
|
||||
mov [rsp],rdi
|
||||
mov [rsp+8],rsi
|
||||
mov [rsp+16],rdx
|
||||
mov [rsp+24],rcx
|
||||
mov [rsp+32],r8
|
||||
|
||||
mov rdi,5
|
||||
mov rsi,rsp
|
||||
int 0x80
|
||||
|
||||
add rsp,40
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro SYSCALL_6 2
|
||||
global %1
|
||||
%1:
|
||||
sub rsp, 48
|
||||
mov eax, %2
|
||||
|
||||
mov [rsp],rdi
|
||||
mov [rsp+8],rsi
|
||||
mov [rsp+16],rdx
|
||||
mov [rsp+24],rcx
|
||||
mov [rsp+32],r8
|
||||
mov [rsp+40],r9
|
||||
|
||||
mov rdi,6
|
||||
mov rsi,rsp
|
||||
int 0x80
|
||||
|
||||
add rsp,48
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%macro SYSCALL_7 2
|
||||
global %1
|
||||
%1:
|
||||
sub rsp, 56
|
||||
mov eax, %7
|
||||
|
||||
mov [rsp],rdi
|
||||
mov [rsp+8],rsi
|
||||
mov [rsp+16],rdx
|
||||
mov [rsp+24],rcx
|
||||
mov [rsp+32],r8
|
||||
mov [rsp+40],r9
|
||||
|
||||
mov rdi,6
|
||||
mov rsi,rsp
|
||||
int 0x80
|
||||
|
||||
add rsp,56
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
SYSCALL_1 syscall_writec, SYSCALL_NUM_writec
|
||||
SYSCALL_0 syscall_xTaskGetTickCount, SYSCALL_NUM_xTaskGetTickCount
|
||||
SYSCALL_2 syscall_xTaskDelayUntil, SYSCALL_NUM_xTaskDelayUntil
|
||||
SYSCALL_4 syscall_xQueueGenericSend, SYSCALL_NUM_xQueueGenericSend
|
||||
SYSCALL_3 syscall_xQueueReceive, SYSCALL_NUM_xQueueReceive
|
||||
SYSCALL_5 syscall_xTimerGenericCommandFromTask, SYSCALL_NUM_xQueueGenericSend
|
||||
SYSCALL_1 syscall_eTaskGetState, SYSCALL_NUM_eTaskGetState
|
||||
SYSCALL_1 syscall_pcQueueGetName, SYSCALL_NUM_pcQueueGetName
|
||||
SYSCALL_1 syscall_pcTimerGetName, SYSCALL_NUM_pcTimerGetName
|
||||
SYSCALL_1 syscall_pvTimerGetTimerID, SYSCALL_NUM_pvTimerGetTimerID
|
||||
SYSCALL_3 syscall_ulTaskGenericNotifyTake, SYSCALL_NUM_ulTaskGenericNotifyTake
|
||||
SYSCALL_3 syscall_ulTaskGenericNotifyValueClear, SYSCALL_NUM_ulTaskGenericNotifyValueClear
|
||||
SYSCALL_1 syscall_uxQueueMessagesWaiting, SYSCALL_NUM_uxQueueMessagesWaiting
|
||||
SYSCALL_1 syscall_uxQueueSpacesAvailable, SYSCALL_NUM_uxQueueSpacesAvailable
|
||||
SYSCALL_0 syscall_uxTaskGetNumberOfTasks, SYSCALL_NUM_uxTaskGetNumberOfTasks
|
||||
SYSCALL_3 syscall_uxTaskGetSystemState, SYSCALL_NUM_uxTaskGetSystemState
|
||||
SYSCALL_1 syscall_uxTaskPriorityGet, SYSCALL_NUM_uxTaskPriorityGet
|
||||
SYSCALL_1 syscall_uxTimerGetReloadMode, SYSCALL_NUM_uxTimerGetReloadMode
|
||||
SYSCALL_2 syscall_vQueueAddToRegistry, SYSCALL_NUM_vQueueAddToRegistry
|
||||
SYSCALL_1 syscall_vQueueUnregisterQueue, SYSCALL_NUM_vQueueUnregisterQueue
|
||||
SYSCALL_1 syscall_vTaskDelay, SYSCALL_NUM_vTaskDelay
|
||||
SYSCALL_4 syscall_vTaskGetInfo, SYSCALL_NUM_vTaskGetInfo
|
||||
SYSCALL_1 syscall_vTaskResume, SYSCALL_NUM_vTaskResume
|
||||
SYSCALL_1 syscall_vTaskSetTimeOutState, SYSCALL_NUM_vTaskSetTimeOutState
|
||||
SYSCALL_1 syscall_vTaskSuspend, SYSCALL_NUM_vTaskSuspend
|
||||
SYSCALL_0 syscall_vTaskSuspendAll, SYSCALL_NUM_vTaskSuspendAll
|
||||
SYSCALL_2 syscall_vTimerSetReloadMode, SYSCALL_NUM_vTimerSetReloadMode
|
||||
SYSCALL_2 syscall_vTimerSetTimerID, SYSCALL_NUM_vTimerSetTimerID
|
||||
SYSCALL_2 syscall_xQueueAddToSet, SYSCALL_NUM_xQueueAddToSet
|
||||
SYSCALL_1 syscall_xQueueGiveMutexRecursive, SYSCALL_NUM_xQueueGiveMutexRecursive
|
||||
SYSCALL_3 syscall_xQueuePeek, SYSCALL_NUM_xQueuePeek
|
||||
SYSCALL_2 syscall_xQueueRemoveFromSet, SYSCALL_NUM_xQueueRemoveFromSet
|
||||
SYSCALL_2 syscall_xQueueSelectFromSet, SYSCALL_NUM_xQueueSelectFromSet
|
||||
SYSCALL_2 syscall_xQueueSemaphoreTake, SYSCALL_NUM_xQueueSemaphoreTake
|
||||
SYSCALL_2 syscall_xQueueTakeMutexRecursive, SYSCALL_NUM_xQueueTakeMutexRecursive
|
||||
SYSCALL_2 syscall_xTaskCheckForTimeOut, SYSCALL_NUM_xTaskCheckForTimeOut
|
||||
SYSCALL_5 syscall_xTaskGenericNotify, SYSCALL_NUM_xTaskGenericNotify
|
||||
SYSCALL_2 syscall_xTaskGenericNotifyStateClear, SYSCALL_NUM_xTaskGenericNotifyStateClear
|
||||
SYSCALL_5 syscall_xTaskGenericNotifyWait, SYSCALL_NUM_xTaskGenericNotifyWait
|
||||
SYSCALL_0 syscall_xTaskGetCurrentTaskHandle, SYSCALL_NUM_xTaskGetCurrentTaskHandle
|
||||
SYSCALL_0 syscall_xTaskGetSchedulerState, SYSCALL_NUM_xTaskGetSchedulerState
|
||||
SYSCALL_1 syscall_xTimerGetExpiryTime, SYSCALL_NUM_xTimerGetExpiryTime
|
||||
SYSCALL_1 syscall_xTimerGetPeriod, SYSCALL_NUM_xTimerGetPeriod
|
||||
SYSCALL_0 syscall_xTimerGetTimerDaemonTaskHandle, SYSCALL_NUM_xTimerGetTimerDaemonTaskHandle
|
||||
SYSCALL_1 syscall_xTimerIsTimerActive, SYSCALL_NUM_xTimerIsTimerActive
|
||||
SYSCALL_1 syscall_xTaskAbortDelay, SYSCALL_NUM_xTaskAbortDelay
|
||||
SYSCALL_1 syscall_xTaskGetHandle, SYSCALL_NUM_xTaskGetHandle
|
||||
SYSCALL_0 syscall_xEventGroupCreate, SYSCALL_NUM_xEventGroupCreate
|
||||
SYSCALL_5 syscall_xEventGroupWaitBits, SYSCALL_NUM_xEventGroupWaitBits
|
||||
SYSCALL_1 syscall_vEventGroupDelete, SYSCALL_NUM_vEventGroupDelete
|
||||
SYSCALL_5 syscall_xStreamBufferGenericCreate, SYSCALL_NUM_xStreamBufferGenericCreate
|
||||
SYSCALL_4 syscall_xStreamBufferReceive, SYSCALL_NUM_xStreamBufferReceive
|
||||
SYSCALL_1 syscall_vStreamBufferDelete, SYSCALL_NUM_vStreamBufferDelete
|
||||
SYSCALL_1 syscall_xQueueGetMutexHolder, SYSCALL_NUM_xQueueGetMutexHolder
|
||||
SYSCALL_4 syscall_xEventGroupSync, SYSCALL_NUM_xEventGroupSync
|
||||
SYSCALL_2 syscall_xEventGroupSetBits, SYSCALL_NUM_xEventGroupSetBits
|
||||
SYSCALL_2 syscall_xEventGroupClearBits, SYSCALL_NUM_xEventGroupClearBits
|
||||
SYSCALL_2 syscall_xStreamBufferSend, SYSCALL_NUM_xStreamBufferSend
|
||||
SYSCALL_1 syscall_xStreamBufferIsEmpty, SYSCALL_NUM_xStreamBufferIsEmpty
|
||||
SYSCALL_1 syscall_xStreamBufferNextMessageLengthBytes, SYSCALL_NUM_xStreamBufferNextMessageLengthBytes
|
||||
SYSCALL_1 syscall_xStreamBufferIsFull, SYSCALL_NUM_xStreamBufferIsFull
|
||||
SYSCALL_1 syscall_xStreamBufferSpacesAvailable, SYSCALL_NUM_xStreamBufferSpacesAvailable
|
||||
SYSCALL_1 syscall_xStreamBufferReset, SYSCALL_NUM_xStreamBufferReset
|
||||
SYSCALL_1 syscall_xStreamBufferBytesAvailable, SYSCALL_NUM_xStreamBufferBytesAvailable
|
||||
|
||||
40
portable/GCC/XEN_x86/x86-64/asm_src/xennote.S
Normal file
40
portable/GCC/XEN_x86/x86-64/asm_src/xennote.S
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
# xennote
|
||||
#
|
||||
# Copyright (C) 2025 Advanced Micro Devices, Inc. or its affiliates. All Rights Reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
# this software and associated documentation files (the "Software"), to deal in
|
||||
# the Software without restriction, including without limitation the rights to
|
||||
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
# the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
.extern start
|
||||
#define ELFNOTE(name, type, desc) \
|
||||
.pushsection .note.name ; \
|
||||
.align 4 ; \
|
||||
.long 2f - 1f /* namesz */ ; \
|
||||
.long 4f - 3f /* descsz */ ; \
|
||||
.long type /* type */ ; \
|
||||
1:.asciz #name /* name */ ; \
|
||||
2:.align 4 ; \
|
||||
3:desc /* desc */ ; \
|
||||
4:.align 4 ; \
|
||||
.popsection
|
||||
|
||||
#define XEN_ELFNOTE_PHYS32_ENTRY 18
|
||||
ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY, .long start)
|
||||
|
||||
1150
portable/GCC/XEN_x86/x86-64/mpu_wrappers_x86_64.c
Normal file
1150
portable/GCC/XEN_x86/x86-64/mpu_wrappers_x86_64.c
Normal file
File diff suppressed because it is too large
Load diff
112
portable/GCC/XEN_x86/x86-64/page_allocate.c
Normal file
112
portable/GCC/XEN_x86/x86-64/page_allocate.c
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
|
||||
/* page_allocate
|
||||
*
|
||||
* Copyright (C) 2025 Advanced Micro Devices, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "stdint.h"
|
||||
#include "x86_64.h"
|
||||
#include "stdio.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include <memory.h>
|
||||
|
||||
void vAlignedFree(void *aligned_ptr) ;
|
||||
void vFreeAllPages(uint64_t *pgd) ;
|
||||
uint64_t *pMallocPageTable(void) ;
|
||||
void vMapPages(uint64_t start_addr,uint64_t end_addr, uint64_t *pgd, uint32_t mode) ;
|
||||
|
||||
void vAlignedFree(void *aligned_ptr) {
|
||||
if (aligned_ptr != NULL) {
|
||||
void *original_ptr = ((void **)aligned_ptr)[-1];
|
||||
vPortFree(original_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void vFreeAllPages(uint64_t *pgd) {
|
||||
if (pgd !=NULL) {
|
||||
for (int pgd_index=256;pgd_index<512;pgd_index++) {
|
||||
uint64_t *pud = (uint64_t *)(pgd[pgd_index]&0xfffffffff000ULL);
|
||||
if (pud !=NULL) {
|
||||
for (int pud_index=0;pud_index<512;pud_index++) {
|
||||
uint64_t *pmd = (uint64_t *)(pud[pud_index]&0xfffffffff000ULL);
|
||||
if (pmd !=NULL) {
|
||||
for (int pmd_index=0;pmd_index<512;pmd_index++) {
|
||||
uint64_t *pt = (uint64_t *)(pmd[pmd_index]&0xfffffffff000ULL);
|
||||
if (pt!=NULL) {
|
||||
vAlignedFree(pt);
|
||||
}
|
||||
}
|
||||
vAlignedFree(pmd);
|
||||
}
|
||||
}
|
||||
vAlignedFree(pud);
|
||||
}
|
||||
}
|
||||
vAlignedFree(pgd);
|
||||
}
|
||||
}
|
||||
uint64_t *pMallocPageTable(void) {
|
||||
uint64_t *page_table=(uint64_t *)pvAlignedMalloc((uint64_t)512 * sizeof(uint64_t),4096);
|
||||
memset(page_table,0,(uint64_t)512*sizeof(uint64_t));
|
||||
return page_table;
|
||||
}
|
||||
void vMapPages(uint64_t start_addr,uint64_t end_addr, uint64_t *pgd, uint32_t mode) {
|
||||
uint32_t pgd_index = 0;
|
||||
uint32_t pud_index = 0;
|
||||
uint32_t pmd_index = 0;
|
||||
uint32_t pt_index = 0;
|
||||
uint64_t addr = start_addr;
|
||||
uint64_t target_address = USER_VA_START + start_addr;
|
||||
|
||||
while (addr < end_addr) {
|
||||
pgd_index = PGD_INDEX(target_address);
|
||||
pud_index = PUD_INDEX(target_address);
|
||||
pmd_index = PMD_INDEX(target_address);
|
||||
pt_index = PT_INDEX(target_address);
|
||||
uint64_t *pud = (uint64_t *)(pgd[pgd_index]&0xfffffffff000ULL);
|
||||
if (pud == (void *)0) {
|
||||
pud = pMallocPageTable();
|
||||
pgd[pgd_index] = (uint64_t) pud;
|
||||
pgd[pgd_index] |= 0x07;
|
||||
}
|
||||
uint64_t *pmd = (uint64_t *)(pud[pud_index]&0xfffffffff000ULL);
|
||||
if (pmd == (void *)0) {
|
||||
pmd = pMallocPageTable();
|
||||
pud[pud_index] = (uint64_t) pmd;
|
||||
pud[pud_index] |= 0x07;
|
||||
}
|
||||
uint64_t *pt = (uint64_t *)(pmd[pmd_index]&0xfffffffff000ULL);
|
||||
if (pt == (void *)0) {
|
||||
pt = pMallocPageTable();
|
||||
pmd[pmd_index] = (uint64_t) pt;
|
||||
pmd[pmd_index] |= 0x07;
|
||||
}
|
||||
pt[pt_index] = addr | (uint64_t)0x07;
|
||||
if (mode != REGION_RW)
|
||||
pt[pt_index] &= ~0x2;
|
||||
addr += PAGE_SIZE_4K;
|
||||
target_address += PAGE_SIZE_4K;
|
||||
}
|
||||
}
|
||||
402
portable/GCC/XEN_x86/x86-64/port.c
Normal file
402
portable/GCC/XEN_x86/x86-64/port.c
Normal file
|
|
@ -0,0 +1,402 @@
|
|||
/*
|
||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "trap.h"
|
||||
#include "x86_64.h"
|
||||
#include "sectionapi.h"
|
||||
#include "ioapic.h"
|
||||
#include "io.h"
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
/* A critical section is exited when the critical section nesting count reaches
|
||||
* this value. */
|
||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||
|
||||
/* This is the lowest possible ISR vector available to application code. */
|
||||
#define portAPIC_MIN_ALLOWABLE_VECTOR ( 0x20 )
|
||||
|
||||
/* EFLAGS bits. */
|
||||
#define portEFLAGS_IF ( 0x200UL )
|
||||
|
||||
/* If configASSERT() is defined then the system stack is filled with this value
|
||||
* to allow for a crude stack overflow check. */
|
||||
#define portSTACK_WORD ( 0xecececec )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Starts the first task executing.
|
||||
*/
|
||||
void vPortStartFirstTask( void );
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
|
||||
const struct xMEMORY_REGION * const xRegions,
|
||||
StackType_t * pxBottomOfStack,
|
||||
configSTACK_DEPTH_TYPE uxStackDepth );
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters,
|
||||
BaseType_t xRunPrivileged,
|
||||
xMPU_SETTINGS * xMPUSettings);
|
||||
void vPortTaskUsesFPU( void );
|
||||
static void prvSetupLAPIC( void );
|
||||
void vPortSetupIDT( void );
|
||||
BaseType_t xPortStartScheduler( void );
|
||||
void vPortEndScheduler( void );
|
||||
void vPortEnterCritical( void );
|
||||
void vPortExitCritical( void );
|
||||
uint32_t ulPortSetInterruptMask( void );
|
||||
void vPortClearInterruptMask( uint32_t ulNewMaskValue );
|
||||
void enable_sci(void);
|
||||
void init_time(void);
|
||||
|
||||
|
||||
|
||||
extern struct TSS Tss;
|
||||
|
||||
/* A variable is used to keep track of the critical section nesting. This
|
||||
* variable must be initialised to a non zero value to ensure interrupts don't
|
||||
* inadvertently become unmasked before the scheduler starts. It is set to zero
|
||||
* before the first task starts executing. */
|
||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||
|
||||
|
||||
/* Saved as part of the task context. If pucPortTaskFPUContextBuffer is NULL
|
||||
* then the task does not have an FPU context. If pucPortTaskFPUContextBuffer is
|
||||
* not NULL then it points to a buffer into which the FPU context can be saved. */
|
||||
#define portFPU_CONTEXT_SIZE_BYTES 512
|
||||
uint8_t pucPortTaskFPUContextBuffer [portFPU_CONTEXT_SIZE_BYTES] __attribute__((aligned(16)));
|
||||
uint32_t xTaskUsesFPU = pdFALSE;
|
||||
|
||||
/* The stack used by interrupt handlers. */
|
||||
static uint64_t ulSystemStack[ configISR_STACK_SIZE ] __attribute__( ( used ) ) = { 0 };
|
||||
|
||||
/* Don't use the very top of the system stack so the return address
|
||||
* appears as 0 if the debugger tries to unwind the stack. */
|
||||
volatile uint64_t ulTopOfSystemStack __attribute__( ( used ) ) = ( uint64_t ) &( ulSystemStack[ configISR_STACK_SIZE - 5 ] );
|
||||
|
||||
|
||||
/* If a yield is requested from an interrupt or from a critical section then
|
||||
* the yield is not performed immediately, and ulPortYieldPending is set to pdTRUE
|
||||
* instead to indicate the yield should be performed at the end of the interrupt
|
||||
* when the critical section is exited. */
|
||||
volatile uint32_t ulPortYieldPending __attribute__( ( used ) ) = pdFALSE;
|
||||
volatile uint32_t schedStart __attribute__( ( used ) ) = pdFALSE;
|
||||
|
||||
/* Counts the interrupt nesting depth. Used to know when to switch to the
|
||||
* interrupt/system stack and when to save/restore a complete context. */
|
||||
volatile uint32_t ulInterruptNesting __attribute__( ( used ) ) = 0;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int vHaltCPU(void) ;
|
||||
int vHaltCPU(void) {
|
||||
__asm__ volatile("hlt");
|
||||
return 1;
|
||||
}
|
||||
|
||||
extern StackType_t *pxCurrentTCB;
|
||||
void vPortStartFirstTask() {
|
||||
schedStart = pdTRUE;
|
||||
struct TrapFrame* tf = (struct TrapFrame*) *pxCurrentTCB;
|
||||
xMPU_SETTINGS * xMPUSettings = (xMPU_SETTINGS*) (pxCurrentTCB+1);
|
||||
load_cr3(xMPUSettings->pgd);
|
||||
Tss.rsp0 = (uint64_t) xMPUSettings->kernel_stack;
|
||||
starttask((void*)*pxCurrentTCB);
|
||||
}
|
||||
|
||||
/*
|
||||
* This method is called by FreeRTOS to store
|
||||
*/
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
|
||||
const struct xMEMORY_REGION * const xRegions,
|
||||
StackType_t * pxBottomOfStack,
|
||||
configSTACK_DEPTH_TYPE uxStackDepth )
|
||||
{
|
||||
extern uint64_t pml4;
|
||||
if (uxStackDepth > 0 ) {
|
||||
xMPUSettings->kernel_stack = &ulSystemStack[configMINIMAL_STACK_SIZE-1];
|
||||
if (xRegions != NULL) {
|
||||
// Allocate page table
|
||||
uint64_t *pgd = pMallocPageTable();
|
||||
for (int region_index = 0; region_index < portNUM_CONFIGURABLE_REGIONS; region_index++) {
|
||||
if (xRegions[region_index].pvBaseAddress == 0) {
|
||||
// last defined index
|
||||
break;
|
||||
}
|
||||
vMapPages((uint64_t) xRegions[region_index].pvBaseAddress, ((uint64_t)xRegions[region_index].pvBaseAddress) + xRegions[region_index].ulLengthInBytes, pgd, xRegions[region_index].ulParameters);
|
||||
// Copy half page tables address from kernel
|
||||
(void) memcpy(pgd, &pml4, PAGE_TABLE_SIZE/2*sizeof(uint64_t));
|
||||
}
|
||||
xMPUSettings->pgd = (uint64_t) pgd;
|
||||
} else {
|
||||
xMPUSettings->pgd = (uint64_t) &pml4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters,
|
||||
BaseType_t xRunPrivileged,
|
||||
xMPU_SETTINGS * xMPUSettings)
|
||||
{
|
||||
uint32_t ulCodeSegment;
|
||||
|
||||
pxTopOfStack = (StackType_t *)(pxTopOfStack - sizeof(struct TrapFrame));
|
||||
struct TrapFrame* tf = (struct TrapFrame *)pxTopOfStack;
|
||||
tf->rdi = (uint64_t) pvParameters;
|
||||
tf->cs = 0x8;
|
||||
tf->rip = (uint64_t) pxCode;
|
||||
tf->ss = 0x10;
|
||||
tf->rsp = (uint64_t) pxTopOfStack;
|
||||
tf->rflags = 0x202;
|
||||
int param = 0;
|
||||
if (xRunPrivileged == 0) {
|
||||
Tss.rsp0 = (uint64_t) xMPUSettings->kernel_stack;
|
||||
tf->cs = (int64_t)((int64_t)0x18|(int64_t)0x3);
|
||||
tf->ss = (int64_t)((int64_t)0x20|(int64_t)0x3);
|
||||
tf->rip = USER_VA_START+(uint64_t)pxCode;
|
||||
}
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
#if defined( configSUPPORT_FPU )
|
||||
#if ( configSUPPORT_FPU == 1 )
|
||||
|
||||
void vPortTaskUsesFPU( void )
|
||||
{
|
||||
/* A task is registering the fact that it needs an FPU context. Allocate a
|
||||
* buffer into which the context can be saved. */
|
||||
xTaskUsesFPU = pdTRUE;
|
||||
/* Initialise the floating point registers. */
|
||||
__asm volatile ( "fninit" );
|
||||
}
|
||||
|
||||
#endif /* configSUPPORT_FPU */
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
#define portAPIC_LVT_ERROR_VECTOR ( 0xfe )
|
||||
#define portAPIC_SPURIOUS_INT_VECTOR ( 0xff )
|
||||
//#define configCPU_CLOCK_HZ ( 2994354000UL )
|
||||
#define configCPU_CLOCK_HZ ( 400000000UL )
|
||||
|
||||
|
||||
static void prvSetupLAPIC( void )
|
||||
{
|
||||
/* Initialise LAPIC to a well known state. */
|
||||
portAPIC_LDR = 0xFFFFFFFF;
|
||||
portAPIC_LDR = ( ( portAPIC_LDR & 0x00FFFFFF ) | 0x00000001 );
|
||||
portAPIC_LVT_TIMER = portAPIC_DISABLE;
|
||||
portAPIC_LVT_PERF = portAPIC_NMI;
|
||||
portAPIC_LVT_LINT0 = portAPIC_DISABLE;
|
||||
portAPIC_LVT_LINT1 = portAPIC_DISABLE;
|
||||
portAPIC_TASK_PRIORITY = 0;
|
||||
|
||||
/* Enable the APIC, mapping the spurious interrupt at the same time. */
|
||||
portAPIC_SPURIOUS_INT = portAPIC_SPURIOUS_INT_VECTOR | portAPIC_ENABLE_BIT;
|
||||
|
||||
/* Set timer error vector. */
|
||||
portAPIC_LVT_ERROR = portAPIC_LVT_ERROR_VECTOR;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define PIC1 0x20
|
||||
#define PIC2 0xA0
|
||||
#define PIC1_COMMAND PIC1
|
||||
#define PIC1_DATA (PIC1+1)
|
||||
#define PIC2_COMMAND PIC2
|
||||
#define PIC2_DATA (PIC2+1)
|
||||
|
||||
void vPortSetupIDT( void )
|
||||
{
|
||||
// Disable interrupts from 8259
|
||||
outb(PIC1_COMMAND, 0x21);
|
||||
outb(PIC1_DATA, 0xFF);
|
||||
outb(PIC1_COMMAND, 0x22);
|
||||
outb(PIC1_DATA, 0xFF);
|
||||
vIDTInit();
|
||||
prvSetupLAPIC();
|
||||
set_ioapic_irq_mask(portAPIC_TIMER_INT_VECTOR-0x20, 0);
|
||||
enable_sci();
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* Initialise Interrupt Descriptor Table (IDT). */
|
||||
vPortSetupIDT();
|
||||
|
||||
init_time();
|
||||
|
||||
/* Make sure the stack used by interrupts is aligned. */
|
||||
ulTopOfSystemStack &= ~portBYTE_ALIGNMENT_MASK;
|
||||
|
||||
ulCriticalNesting = 0;
|
||||
/* Enable LAPIC Counter.*/
|
||||
// portAPIC_LVT_TIMER = portAPIC_TIMER_PERIODIC | portAPIC_TIMER_INT_VECTOR;
|
||||
|
||||
/* Sometimes needed. */
|
||||
// portAPIC_TMRDIV = portAPIC_DIV_16;
|
||||
|
||||
/* Should not return from the following function as the scheduler will then
|
||||
* be executing the tasks. */
|
||||
vPortStartFirstTask();
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
* Artificially force an assert. */
|
||||
configASSERT( ulCriticalNesting == 1000UL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
if( ulCriticalNesting == 0UL )
|
||||
{
|
||||
__asm volatile ( "cli" );
|
||||
}
|
||||
|
||||
/* Now that interrupts are disabled, ulCriticalNesting can be accessed
|
||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
* portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortExitCritical( void )
|
||||
{
|
||||
if( ulCriticalNesting > 0UL )
|
||||
{
|
||||
/* Decrement the nesting count as the critical section is being
|
||||
* exited. */
|
||||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then all interrupt
|
||||
* priorities must be re-enabled. */
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
__asm volatile ( "sti" );
|
||||
|
||||
/* If a yield was pended from within the critical section then
|
||||
* perform the yield now. */
|
||||
if( ulPortYieldPending != pdFALSE )
|
||||
{
|
||||
ulPortYieldPending = pdFALSE;
|
||||
__asm volatile ( portYIELD_INTERRUPT );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint32_t ulPortSetInterruptMask( void )
|
||||
{
|
||||
volatile uint64_t ulOriginalMask;
|
||||
|
||||
/* Set mask to max syscall priority. */
|
||||
#if defined (configMAX_API_CALL_INTERRUPT_PRIORITY)
|
||||
#if defined (portMAX_PRIORITY)
|
||||
#if ( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY )
|
||||
{
|
||||
/* Return whether interrupts were already enabled or not. Pop adjusts
|
||||
* the stack first. */
|
||||
__asm__ volatile (
|
||||
"pushfq \n\t"
|
||||
"popq %%rax \n\t"
|
||||
"cli \n\t"
|
||||
"movq %%rax, %0 \n\t"
|
||||
: "=r" (ulOriginalMask)
|
||||
:
|
||||
: "rax", "memory"
|
||||
);
|
||||
|
||||
ulOriginalMask &= portEFLAGS_IF;
|
||||
}
|
||||
#else
|
||||
{
|
||||
/* Return original mask. */
|
||||
ulOriginalMask = portAPIC_TASK_PRIORITY;
|
||||
portAPIC_TASK_PRIORITY = portMAX_API_CALL_PRIORITY;
|
||||
configASSERT( portAPIC_TASK_PRIORITY == portMAX_API_CALL_PRIORITY );
|
||||
}
|
||||
#endif /* if ( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY ) */
|
||||
#endif
|
||||
#endif
|
||||
return ulOriginalMask;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
void vPortClearInterruptMask( uint32_t ulNewMaskValue )
|
||||
{
|
||||
#if defined (configMAX_API_CALL_INTERRUPT_PRIORITY)
|
||||
#if defined (portMAX_PRIORITY)
|
||||
#if ( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY )
|
||||
{
|
||||
if( ulNewMaskValue != pdFALSE )
|
||||
{
|
||||
__asm volatile ( "sti" );
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
portAPIC_TASK_PRIORITY = ulNewMaskValue;
|
||||
configASSERT( portAPIC_TASK_PRIORITY == ulNewMaskValue );
|
||||
}
|
||||
#endif /* if ( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY ) */
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
FREERTOS_SYSTEM_CALL int vPortIsPrivileged(void) {
|
||||
unsigned short cs =(unsigned short)0;
|
||||
// Read the Code Segment (CS) register
|
||||
__asm__ __volatile__("mov %%cs, %0" : "=r"(cs));
|
||||
// Check if the Current Privilege Level (CPL) is 0 (Ring 0)
|
||||
if ((cs & (unsigned short)0x3) ==(unsigned short) 0) {
|
||||
return 1; // In Ring 0
|
||||
} else {
|
||||
return 0; // Not in Ring 0
|
||||
}
|
||||
}
|
||||
253
portable/GCC/XEN_x86/x86-64/portmacro.h
Normal file
253
portable/GCC/XEN_x86/x86-64/portmacro.h
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||
* and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint64_t
|
||||
#define portBASE_TYPE long
|
||||
#define portPOINTER_SIZE_TYPE uint64_t
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
typedef BaseType_t TickType_t;
|
||||
#define portMAX_DELAY ( ( TickType_t ) 0xffffffffUL )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 32
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task utilities. */
|
||||
|
||||
/* The interrupt priority (for vectors 16 to 255) is determined using vector/16.
|
||||
* The quotient is rounded to the nearest integer with 1 being the lowest priority
|
||||
* and 15 is the highest. Therefore the following two interrupts are at the lowest
|
||||
* priority. *NOTE 1* If the yield vector is changed then it must also be changed
|
||||
* in the portYIELD_INTERRUPT definition immediately below. */
|
||||
#define portAPIC_TIMER_INT_VECTOR ( 0x20 )
|
||||
#define portAPIC_DEBUG_SERIAL_INT_VECTOR ( 0x24 )
|
||||
#define portAPIC_YIELD_INT_VECTOR ( 0x21 )
|
||||
|
||||
/* Build yield interrupt instruction. */
|
||||
#define portYIELD_INTERRUPT "int $0x21"
|
||||
|
||||
/* APIC register addresses. */
|
||||
#define portAPIC_EOI ( *( ( volatile uint32_t * ) 0xFEE000B0UL ) )
|
||||
|
||||
/* APIC bit definitions. */
|
||||
#define portAPIC_ENABLE_BIT ( 1UL << 8UL )
|
||||
#define portAPIC_TIMER_PERIODIC ( 1UL << 17UL )
|
||||
#define portAPIC_DISABLE ( 1UL << 16UL )
|
||||
#define portAPIC_NMI ( 4 << 8 )
|
||||
#define portAPIC_DIV_16 ( 0x03 )
|
||||
|
||||
/* Define local APIC register addresses. */
|
||||
#define configAPIC_BASE 0xFEE00000UL
|
||||
#define portAPIC_ID_REGISTER ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x20UL ) ) )
|
||||
#define portAPIC_SPURIOUS_INT ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xF0UL ) ) )
|
||||
#define portAPIC_LVT_TIMER ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x320UL ) ) )
|
||||
#define portAPIC_TIMER_INITIAL_COUNT ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x380UL ) ) )
|
||||
#define portAPIC_TIMER_CURRENT_COUNT ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x390UL ) ) )
|
||||
#define portAPIC_TASK_PRIORITY ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x80UL ) ) )
|
||||
#define portAPIC_LVT_ERROR ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x370UL ) ) )
|
||||
#define portAPIC_ERROR_STATUS ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x280UL ) ) )
|
||||
#define portAPIC_LDR ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xD0UL ) ) )
|
||||
#define portAPIC_TMRDIV ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x3E0UL ) ) )
|
||||
#define portAPIC_LVT_PERF ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x340UL ) ) )
|
||||
#define portAPIC_LVT_LINT0 ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x350UL ) ) )
|
||||
#define portAPIC_LVT_LINT1 ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x360UL ) ) )
|
||||
|
||||
/* Don't yield if inside a critical section - instead hold the yield pending
|
||||
* so it is performed when the critical section is exited. */
|
||||
#define portYIELD() \
|
||||
{ \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
extern volatile uint32_t ulPortYieldPending; \
|
||||
if( ulCriticalNesting != 0 ) \
|
||||
{ \
|
||||
ulPortYieldPending = pdTRUE; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
__asm volatile ( portYIELD_INTERRUPT ); \
|
||||
} \
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Called at the end of an ISR that can cause a context switch - pend a yield if
|
||||
* xSwitchRequired is not false. */
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
{ \
|
||||
extern volatile uint32_t ulPortYieldPending; \
|
||||
if( xSwitchRequired != pdFALSE ) \
|
||||
{ \
|
||||
ulPortYieldPending = 1; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Same as portEND_SWITCHING_ISR() - take your pick which name to use. */
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Critical section control
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Critical sections for use in interrupts. */
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( x )
|
||||
|
||||
extern int vPortIsPrivileged(void);
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
extern uint32_t ulPortSetInterruptMask( void );
|
||||
extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
|
||||
|
||||
/* These macros do not globally disable/enable interrupts. They do mask off
|
||||
* interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
#define portDISABLE_INTERRUPTS() __asm volatile ( "cli" )
|
||||
#define portENABLE_INTERRUPTS() __asm volatile ( "sti" )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||
* not required for this port but included in case common demo code that uses these
|
||||
* macros is used. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
|
||||
/* Store/clear the ready priorities in a bit map. */
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) \
|
||||
__asm volatile ( "bsr %1, %0\n\t" \
|
||||
: "=r" ( uxTopPriority ) : "rm" ( uxReadyPriorities ) : "cc" )
|
||||
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
#define portNOP() __asm volatile ( "NOP" )
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Misc
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
#define portNUM_VECTORS 256
|
||||
#define portMAX_PRIORITY 15
|
||||
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
|
||||
/* The FreeRTOS scheduling algorithm selects the task that will enter the
|
||||
* Running state. configUSE_PORT_OPTIMISED_TASK_SELECTION is used to set how
|
||||
* that is done.
|
||||
*
|
||||
* If configUSE_PORT_OPTIMISED_TASK_SELECTION is set to 0 then the task to
|
||||
* enter the Running state is selected using a portable algorithm written in
|
||||
* C. This is the slowest method, but the algorithm does not restrict the
|
||||
* maximum number of unique RTOS task priorities that are available.
|
||||
*
|
||||
* If configUSE_PORT_OPTIMISED_TASK_SELECTION is set to 1 then the task to
|
||||
* enter the Running state is selected using a single assembly instruction.
|
||||
* This is the fastest method, but restricts the maximum number of unique RTOS
|
||||
* task priorities to 32 (the same task priority can be assigned to any number
|
||||
* of RTOS tasks). */
|
||||
#warning configUSE_PORT_OPTIMISED_TASK_SELECTION was not defined in FreeRTOSConfig.h and has been defaulted to 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#endif
|
||||
|
||||
/* The value written to the task priority register to raise the interrupt mask
|
||||
* to the maximum from which FreeRTOS API calls can be made. */
|
||||
#define portAPIC_PRIORITY_SHIFT ( 4UL )
|
||||
#define portAPIC_MAX_SUB_PRIORITY ( 0x0fUL )
|
||||
#define portMAX_API_CALL_PRIORITY ( ( configMAX_API_CALL_INTERRUPT_PRIORITY << portAPIC_PRIORITY_SHIFT ) | portAPIC_MAX_SUB_PRIORITY )
|
||||
|
||||
/* Asserts if interrupt safe FreeRTOS functions are called from a priority
|
||||
* above the max system call interrupt priority. */
|
||||
#define portAPIC_PROCESSOR_PRIORITY ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xA0UL ) ) )
|
||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( portAPIC_PROCESSOR_PRIORITY ) <= ( portMAX_API_CALL_PRIORITY ) )
|
||||
|
||||
/* Support for Restricted Tasks */
|
||||
#define portUSING_MPU_WRAPPERS 1
|
||||
|
||||
/*
|
||||
* The following two setting are saved for each task
|
||||
* FreeRTOS saves this information in Task Control Block
|
||||
* and these are used during context switch.
|
||||
*/
|
||||
typedef struct {
|
||||
uint64_t pgd;
|
||||
StackType_t *kernel_stack;
|
||||
} xMPU_SETTINGS;
|
||||
|
||||
/* Allow upto 16 memory regions to be defined.*/
|
||||
#define portNUM_CONFIGURABLE_REGIONS 16
|
||||
#define portPRIVILEGE_BIT 0x80000000UL
|
||||
#define portIS_PRIVILEGED() vPortIsPrivileged()
|
||||
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
579
portable/GCC/XEN_x86/x86-64/syscall.c
Normal file
579
portable/GCC/XEN_x86/x86-64/syscall.c
Normal file
|
|
@ -0,0 +1,579 @@
|
|||
/* syscall
|
||||
*
|
||||
* Copyright (C) 2025 Advanced Micro Devices, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
#include "FreeRTOS.h"
|
||||
#include "syscall.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "trap.h"
|
||||
#include "timers.h"
|
||||
#include "x86_64.h"
|
||||
#include "freertos_serial.h"
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
#define MAX_SYSCALLS 128
|
||||
|
||||
/* Alse file syscall.asm these constants are also defined there */
|
||||
#define SYSCALL_NUM_writec 0
|
||||
#define SYSCALL_NUM_xTaskGetTickCount 1
|
||||
#define SYSCALL_NUM_xTaskDelayUntil 2
|
||||
#define SYSCALL_NUM_xQueueGenericSend 3
|
||||
#define SYSCALL_NUM_xQueueReceive 4
|
||||
#define SYSCALL_NUM_xTimerGenericCommandFromTask 5
|
||||
#define SYSCALL_NUM_eTaskGetState 6
|
||||
#define SYSCALL_NUM_pcQueueGetName 7
|
||||
#define SYSCALL_NUM_pcTimerGetName 8
|
||||
#define SYSCALL_NUM_pvTimerGetTimerID 9
|
||||
#define SYSCALL_NUM_ulTaskGenericNotifyTake 10
|
||||
#define SYSCALL_NUM_ulTaskGenericNotifyValueClear 11
|
||||
#define SYSCALL_NUM_uxQueueMessagesWaiting 12
|
||||
#define SYSCALL_NUM_uxQueueSpacesAvailable 13
|
||||
#define SYSCALL_NUM_uxTaskGetNumberOfTasks 14
|
||||
#define SYSCALL_NUM_uxTaskGetSystemState 15
|
||||
#define SYSCALL_NUM_uxTaskPriorityGet 16
|
||||
#define SYSCALL_NUM_uxTimerGetReloadMode 17
|
||||
#define SYSCALL_NUM_vQueueAddToRegistry 18
|
||||
#define SYSCALL_NUM_vQueueUnregisterQueue 19
|
||||
#define SYSCALL_NUM_vTaskDelay 20
|
||||
#define SYSCALL_NUM_vTaskGetInfo 21
|
||||
#define SYSCALL_NUM_vTaskResume 22
|
||||
#define SYSCALL_NUM_vTaskSetTimeOutState 23
|
||||
#define SYSCALL_NUM_vTaskSuspend 24
|
||||
#define SYSCALL_NUM_vTaskSuspendAll 25
|
||||
#define SYSCALL_NUM_vTimerSetReloadMode 26
|
||||
#define SYSCALL_NUM_vTimerSetTimerID 27
|
||||
#define SYSCALL_NUM_xQueueAddToSet 28
|
||||
#define SYSCALL_NUM_xQueueGiveMutexRecursive 29
|
||||
#define SYSCALL_NUM_xQueuePeek 30
|
||||
#define SYSCALL_NUM_xQueueRemoveFromSet 31
|
||||
#define SYSCALL_NUM_xQueueSelectFromSet 32
|
||||
#define SYSCALL_NUM_xQueueSemaphoreTake 33
|
||||
#define SYSCALL_NUM_xQueueTakeMutexRecursive 34
|
||||
#define SYSCALL_NUM_xTaskCheckForTimeOut 35
|
||||
#define SYSCALL_NUM_xTaskGenericNotify 36
|
||||
#define SYSCALL_NUM_xTaskGenericNotifyStateClear 37
|
||||
#define SYSCALL_NUM_xTaskGenericNotifyWait 38
|
||||
#define SYSCALL_NUM_xTaskGetCurrentTaskHandle 39
|
||||
#define SYSCALL_NUM_xTaskGetSchedulerState 40
|
||||
#define SYSCALL_NUM_xTimerGetExpiryTime 41
|
||||
#define SYSCALL_NUM_xTimerGetPeriod 42
|
||||
#define SYSCALL_NUM_xTimerGetTimerDaemonTaskHandle 43
|
||||
#define SYSCALL_NUM_xTimerIsTimerActive 44
|
||||
#define SYSCALL_NUM_xTaskAbortDelay 45
|
||||
#define SYSCALL_NUM_xTaskGetHandle 46
|
||||
#define SYSCALL_NUM_xEventGroupCreate 47
|
||||
#define SYSCALL_NUM_xEventGroupWaitBits 48
|
||||
#define SYSCALL_NUM_vEventGroupDelete 49
|
||||
#define SYSCALL_NUM_xStreamBufferGenericCreate 50
|
||||
#define SYSCALL_NUM_xStreamBufferReceive 51
|
||||
#define SYSCALL_NUM_vStreamBufferDelete 52
|
||||
#define SYSCALL_NUM_xQueueGetMutexHolder 53
|
||||
#define SYSCALL_NUM_xEventGroupSync 54
|
||||
#define SYSCALL_NUM_xEventGroupSetBits 55
|
||||
#define SYSCALL_NUM_xEventGroupClearBits 56
|
||||
#define SYSCALL_NUM_xStreamBufferSend 57
|
||||
#define SYSCALL_NUM_xStreamBufferIsEmpty 58
|
||||
#define SYSCALL_NUM_xStreamBufferNextMessageLengthBytes 59
|
||||
#define SYSCALL_NUM_xStreamBufferIsFull 60
|
||||
#define SYSCALL_NUM_xStreamBufferSpacesAvailable 61
|
||||
#define SYSCALL_NUM_xStreamBufferReset 62
|
||||
#define SYSCALL_NUM_xStreamBufferBytesAvailable 64
|
||||
|
||||
static SYSTEMCALL system_calls[MAX_SYSCALLS];
|
||||
|
||||
|
||||
static uint64_t *getpgd() {
|
||||
extern StackType_t *pxCurrentTCB;
|
||||
xMPU_SETTINGS * xMPUSettings = (xMPU_SETTINGS *) (pxCurrentTCB+1);
|
||||
return (uint64_t *) xMPUSettings->pgd;
|
||||
}
|
||||
|
||||
/* Check that a user space address is mapped */
|
||||
int check_address_valid(uint64_t target_address) {
|
||||
uint64_t *pml4=getpgd();
|
||||
uint64_t addr = target_address;
|
||||
if (target_address < USER_VA_START) {
|
||||
return 0;
|
||||
}
|
||||
uint32_t pml4_index=0;
|
||||
uint32_t pml3_index=0;
|
||||
uint32_t pml2_index=0;
|
||||
uint32_t pml1_index=0;
|
||||
uint64_t *pml3, *pml2,*pml1;
|
||||
|
||||
pml4_index = (addr >> 39) & 0x1ff;
|
||||
pml3=(uint64_t *)(pml4[pml4_index]&0xfffffffff000);
|
||||
if (!pml3){
|
||||
return 0;
|
||||
}
|
||||
pml3_index = (addr >> 30) & 0x1ff;
|
||||
pml2=(uint64_t *)(pml3[pml3_index]&0xfffffffff000);
|
||||
if (!pml2){
|
||||
return 0;
|
||||
}
|
||||
pml2_index = (addr >> 21) & 0x1ff;
|
||||
pml1=(uint64_t *)(pml2[pml2_index]&0xfffffffff000);
|
||||
if (!pml1){
|
||||
return 0;
|
||||
}
|
||||
pml1_index = (addr >> 12) & 0x1ff;
|
||||
uint64_t phyaddr = pml1[pml1_index]&0xfffffffff000;
|
||||
if (!phyaddr){
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define CHECK_USER_PARAM(x) \
|
||||
if (!check_address_valid(argptr[x])) \
|
||||
return -1
|
||||
|
||||
uint64_t sys_writec(uint64_t *argptr)
|
||||
{
|
||||
serial_send((char) argptr[0]&0xff);
|
||||
return (uint64_t) 0;
|
||||
}
|
||||
uint64_t sys_xTaskGetTickCount(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (BaseType_t) xTaskGetTickCount();
|
||||
}
|
||||
uint64_t sys_xTaskDelayUntil(uint64_t *argptr)
|
||||
{
|
||||
CHECK_USER_PARAM(0);
|
||||
return (uint64_t) (BaseType_t) xTaskDelayUntil((TickType_t * const) argptr[0],( TickType_t) argptr[1]);
|
||||
}
|
||||
uint64_t sys_xQueueGenericSend(uint64_t *argptr)
|
||||
{
|
||||
CHECK_USER_PARAM(1);
|
||||
return (uint64_t) (BaseType_t) xQueueGenericSend((QueueHandle_t) argptr[0],( const void * const) argptr[1],(TickType_t) argptr[2],( BaseType_t) argptr[3]);
|
||||
}
|
||||
uint64_t sys_xQueueReceive(uint64_t *argptr)
|
||||
{
|
||||
CHECK_USER_PARAM(1);
|
||||
return (uint64_t) (BaseType_t) xQueueReceive((QueueHandle_t) argptr[0],(void * const) argptr[1],(TickType_t) argptr[2]);
|
||||
}
|
||||
uint64_t sys_xTimerGenericCommandFromTask(uint64_t *argptr)
|
||||
{
|
||||
CHECK_USER_PARAM(3);
|
||||
return (uint64_t) (BaseType_t) xTimerGenericCommandFromTask((TimerHandle_t) argptr[0],(const BaseType_t) argptr[1],( const TickType_t) argptr[2],( BaseType_t * const) argptr[3],( const TickType_t) argptr[4]);
|
||||
}
|
||||
uint64_t sys_vTaskDelay(uint64_t *argptr)
|
||||
{
|
||||
vTaskDelay((TickType_t) argptr[0]);
|
||||
return (uint64_t) 0;
|
||||
}
|
||||
uint64_t sys_uxTaskPriorityGet(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (UBaseType_t) uxTaskPriorityGet((const TaskHandle_t) argptr[0]);
|
||||
}
|
||||
uint64_t sys_vTaskPrioritySet(uint64_t *argptr)
|
||||
{
|
||||
vTaskPrioritySet((TaskHandle_t) argptr[0],( UBaseType_t) argptr[1]);
|
||||
return (uint64_t) 0;
|
||||
}
|
||||
uint64_t sys_eTaskGetState(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (eTaskState) eTaskGetState((TaskHandle_t) argptr[0]);
|
||||
}
|
||||
uint64_t sys_vTaskGetInfo(uint64_t *argptr)
|
||||
{
|
||||
CHECK_USER_PARAM(1);
|
||||
vTaskGetInfo((TaskHandle_t) argptr[0],( TaskStatus_t * ) argptr[1],( BaseType_t) argptr[2],( eTaskState) argptr[3]);
|
||||
return (uint64_t) 0;
|
||||
}
|
||||
uint64_t sys_vTaskSuspend(uint64_t *argptr)
|
||||
{
|
||||
vTaskSuspend((TaskHandle_t) argptr[0]);
|
||||
return (uint64_t) 0;
|
||||
}
|
||||
uint64_t sys_vTaskResume(uint64_t *argptr)
|
||||
{
|
||||
vTaskResume((TaskHandle_t) argptr[0]);
|
||||
return (uint64_t) 0;
|
||||
}
|
||||
uint64_t sys_vTaskSuspendAll(uint64_t *argptr)
|
||||
{
|
||||
vTaskSuspendAll();
|
||||
return (uint64_t) 0;
|
||||
}
|
||||
uint64_t sys_uxTaskGetNumberOfTasks(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (UBaseType_t) uxTaskGetNumberOfTasks();
|
||||
}
|
||||
uint64_t sys_uxTaskGetSystemState(uint64_t *argptr)
|
||||
{
|
||||
CHECK_USER_PARAM(0);
|
||||
CHECK_USER_PARAM(2);
|
||||
return (uint64_t) (UBaseType_t) uxTaskGetSystemState((TaskStatus_t *) argptr[0],( UBaseType_t) argptr[1],( configRUN_TIME_COUNTER_TYPE *) argptr[2]);
|
||||
}
|
||||
uint64_t sys_xTaskGetCurrentTaskHandle(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (TaskHandle_t) xTaskGetCurrentTaskHandle();
|
||||
}
|
||||
uint64_t sys_xTaskGetSchedulerState(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (BaseType_t) xTaskGetSchedulerState();
|
||||
}
|
||||
uint64_t sys_vTaskSetTimeOutState(uint64_t *argptr)
|
||||
{
|
||||
CHECK_USER_PARAM(0);
|
||||
vTaskSetTimeOutState((TimeOut_t * const) argptr[0]);
|
||||
return (uint64_t) 0;
|
||||
}
|
||||
uint64_t sys_xTaskCheckForTimeOut(uint64_t *argptr)
|
||||
{
|
||||
CHECK_USER_PARAM(0);
|
||||
CHECK_USER_PARAM(1);
|
||||
return (uint64_t) (BaseType_t) xTaskCheckForTimeOut((TimeOut_t * const) argptr[0],( TickType_t * const) argptr[1]);
|
||||
}
|
||||
uint64_t sys_xTaskGenericNotify(uint64_t *argptr)
|
||||
{
|
||||
CHECK_USER_PARAM(4);
|
||||
return (uint64_t) (BaseType_t) xTaskGenericNotify((TaskHandle_t) argptr[0],( UBaseType_t) argptr[1],( uint32_t) argptr[2],( eNotifyAction) argptr[3],( uint32_t *) argptr[4]);
|
||||
}
|
||||
uint64_t sys_xTaskGenericNotifyWait(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (BaseType_t) xTaskGenericNotifyWait((UBaseType_t) argptr[0],( uint32_t) argptr[1],( uint32_t) argptr[2],( uint32_t *) argptr[3],( TickType_t) argptr[4]);
|
||||
}
|
||||
uint64_t sys_ulTaskGenericNotifyTake(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (uint32_t) ulTaskGenericNotifyTake((UBaseType_t) argptr[0],( BaseType_t) argptr[1],( TickType_t) argptr[2]);
|
||||
}
|
||||
uint64_t sys_xTaskGenericNotifyStateClear(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (BaseType_t) xTaskGenericNotifyStateClear((TaskHandle_t) argptr[0],( UBaseType_t) argptr[1]);
|
||||
}
|
||||
uint64_t sys_ulTaskGenericNotifyValueClear(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (uint32_t) ulTaskGenericNotifyValueClear((TaskHandle_t) argptr[0],( UBaseType_t) argptr[1],( uint32_t) argptr[2]);
|
||||
}
|
||||
uint64_t sys_xQueueGenericReset(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (BaseType_t) xQueueGenericReset((QueueHandle_t) argptr[0],( BaseType_t) argptr[1]);
|
||||
}
|
||||
uint64_t sys_uxQueueMessagesWaiting(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (UBaseType_t) uxQueueMessagesWaiting((const QueueHandle_t) argptr[0]);
|
||||
}
|
||||
uint64_t sys_uxQueueSpacesAvailable(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (UBaseType_t) uxQueueSpacesAvailable((const QueueHandle_t) argptr[0]);
|
||||
}
|
||||
uint64_t sys_xQueuePeek(uint64_t *argptr)
|
||||
{
|
||||
CHECK_USER_PARAM(1);
|
||||
return (uint64_t) (BaseType_t) xQueuePeek((QueueHandle_t) argptr[0],( void * const) argptr[1],( TickType_t) argptr[2]);
|
||||
}
|
||||
uint64_t sys_xQueueSemaphoreTake(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (BaseType_t) xQueueSemaphoreTake((QueueHandle_t) argptr[0],( TickType_t) argptr[1]);
|
||||
}
|
||||
uint64_t sys_xQueueCreateMutex(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (QueueHandle_t) xQueueCreateMutex((const uint8_t) argptr[0]);
|
||||
}
|
||||
uint64_t sys_xQueueCreateCountingSemaphore(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (QueueHandle_t) xQueueCreateCountingSemaphore((UBaseType_t) argptr[0],( UBaseType_t) argptr[1]);
|
||||
}
|
||||
uint64_t sys_xQueueTakeMutexRecursive(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (BaseType_t) xQueueTakeMutexRecursive((QueueHandle_t) argptr[0],( TickType_t) argptr[1]);
|
||||
}
|
||||
uint64_t sys_xQueueGiveMutexRecursive(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (BaseType_t) xQueueGiveMutexRecursive((QueueHandle_t) argptr[0]);
|
||||
}
|
||||
uint64_t sys_xQueueCreateSet(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (QueueSetHandle_t) xQueueCreateSet((UBaseType_t) argptr[0]);
|
||||
}
|
||||
uint64_t sys_xQueueSelectFromSet(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (QueueSetMemberHandle_t) xQueueSelectFromSet((QueueSetHandle_t) argptr[0],( TickType_t) argptr[1]);
|
||||
}
|
||||
uint64_t sys_xQueueAddToSet(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (BaseType_t) xQueueAddToSet((QueueSetMemberHandle_t) argptr[0],( QueueSetHandle_t) argptr[1]);
|
||||
}
|
||||
uint64_t sys_xQueueRemoveFromSet(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (BaseType_t) xQueueRemoveFromSet((QueueSetMemberHandle_t) argptr[0],( QueueSetHandle_t) argptr[1]);
|
||||
}
|
||||
uint64_t sys_vQueueAddToRegistry(uint64_t *argptr)
|
||||
{
|
||||
CHECK_USER_PARAM(1);
|
||||
vQueueAddToRegistry((QueueHandle_t) argptr[0],( const char *) argptr[1]);
|
||||
return (uint64_t) 0;
|
||||
}
|
||||
uint64_t sys_vQueueUnregisterQueue(uint64_t *argptr)
|
||||
{
|
||||
vQueueUnregisterQueue((QueueHandle_t) argptr[0]);
|
||||
return (uint64_t) 0;
|
||||
}
|
||||
uint64_t sys_pcQueueGetName(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (const char *) pcQueueGetName((QueueHandle_t) argptr[0]);
|
||||
}
|
||||
uint64_t sys_vQueueDelete(uint64_t *argptr)
|
||||
{
|
||||
vQueueDelete((QueueHandle_t) argptr[0]);
|
||||
return (uint64_t) 0;
|
||||
}
|
||||
uint64_t sys_pvTimerGetTimerID(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (void *) pvTimerGetTimerID((const TimerHandle_t) argptr[0]);
|
||||
}
|
||||
uint64_t sys_vTimerSetTimerID(uint64_t *argptr)
|
||||
{
|
||||
CHECK_USER_PARAM(1);
|
||||
vTimerSetTimerID((TimerHandle_t) argptr[0],( void *) argptr[1]);
|
||||
return (uint64_t) 0;
|
||||
}
|
||||
uint64_t sys_xTimerIsTimerActive(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (BaseType_t) xTimerIsTimerActive((TimerHandle_t) argptr[0]);
|
||||
}
|
||||
uint64_t sys_xTimerGetTimerDaemonTaskHandle(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (TaskHandle_t) xTimerGetTimerDaemonTaskHandle();
|
||||
}
|
||||
uint64_t sys_vTimerSetReloadMode(uint64_t *argptr)
|
||||
{
|
||||
vTimerSetReloadMode((TimerHandle_t) argptr[0],( const BaseType_t) argptr[1]);
|
||||
return (uint64_t) 0;
|
||||
}
|
||||
uint64_t sys_uxTimerGetReloadMode(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (UBaseType_t) uxTimerGetReloadMode((TimerHandle_t) argptr[0]);
|
||||
}
|
||||
uint64_t sys_pcTimerGetName(uint64_t *argptr)
|
||||
{
|
||||
// Return a pointer.
|
||||
return (uint64_t) (const char *) pcTimerGetName((TimerHandle_t) argptr[0]);
|
||||
}
|
||||
uint64_t sys_xTimerGetPeriod(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (TickType_t) xTimerGetPeriod((TimerHandle_t) argptr[0]);
|
||||
}
|
||||
uint64_t sys_xTimerGetExpiryTime(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (TickType_t) xTimerGetExpiryTime((TimerHandle_t) argptr[0]);
|
||||
}
|
||||
|
||||
uint64_t sys_xTaskAbortDelay(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (BaseType_t) xTaskAbortDelay((TaskHandle_t) argptr[0]);
|
||||
}
|
||||
|
||||
uint64_t sys_xTaskGetHandle(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (TaskHandle_t) xTaskGetHandle((const char *) argptr[0]);
|
||||
}
|
||||
|
||||
uint64_t sys_xEventGroupCreate(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (EventGroupHandle_t) xEventGroupCreate();
|
||||
}
|
||||
|
||||
uint64_t sys_xEventGroupWaitBits(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (EventBits_t) xEventGroupWaitBits((EventGroupHandle_t) argptr[0], (const EventBits_t) argptr[1], (const BaseType_t) argptr[2], (const BaseType_t)argptr[3], (TickType_t)argptr[4]);
|
||||
}
|
||||
|
||||
|
||||
uint64_t sys_vEventGroupDelete(uint64_t *argptr)
|
||||
{
|
||||
CHECK_USER_PARAM(0);
|
||||
vEventGroupDelete((EventGroupHandle_t) argptr[0]);
|
||||
return (uint64_t) 0;
|
||||
}
|
||||
|
||||
uint64_t sys_xStreamBufferGenericCreate(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (StreamBufferHandle_t) xStreamBufferGenericCreate((size_t) argptr[0], (size_t) argptr[1], (BaseType_t) argptr[2], (StreamBufferCallbackFunction_t )argptr[3], (StreamBufferCallbackFunction_t)argptr[4]);
|
||||
}
|
||||
|
||||
uint64_t sys_xStreamBufferReceive(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (size_t) xStreamBufferReceive((StreamBufferHandle_t) argptr[0], (void *) argptr[1], (size_t) argptr[2], (TickType_t)argptr[3]);
|
||||
}
|
||||
|
||||
uint64_t sys_vStreamBufferDelete(uint64_t *argptr)
|
||||
{
|
||||
CHECK_USER_PARAM(0);
|
||||
vStreamBufferDelete((StreamBufferHandle_t) argptr[0]);
|
||||
return (uint64_t) 0;
|
||||
}
|
||||
uint64_t sys_xQueueGetMutexHolder(uint64_t *argptr)
|
||||
{
|
||||
CHECK_USER_PARAM(1);
|
||||
return (uint64_t) (TaskHandle_t) xQueueGetMutexHolder((QueueHandle_t) argptr[0]);
|
||||
}
|
||||
|
||||
uint64_t sys_xEventGroupSync(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (EventBits_t) xEventGroupSync((EventGroupHandle_t) argptr[0], (const EventBits_t) argptr[1], (const EventBits_t ) argptr[2], (TickType_t )argptr[3]);
|
||||
}
|
||||
|
||||
uint64_t sys_xEventGroupSetBits(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) ( EventBits_t) xEventGroupSetBits((EventGroupHandle_t) argptr[0], (const EventBits_t) argptr[1]);
|
||||
}
|
||||
|
||||
uint64_t sys_xEventGroupClearBits(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) ( EventBits_t) xEventGroupClearBits((EventGroupHandle_t) argptr[0], (const EventBits_t) argptr[1]);
|
||||
}
|
||||
|
||||
uint64_t sys_xStreamBufferSend(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (size_t) xStreamBufferSend((StreamBufferHandle_t) argptr[0], (const void *) argptr[1], (size_t) argptr[2], (TickType_t)argptr[3]);
|
||||
}
|
||||
|
||||
uint64_t sys_xStreamBufferIsEmpty(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) ( size_t ) xStreamBufferIsEmpty((StreamBufferHandle_t) argptr[0]);
|
||||
}
|
||||
|
||||
uint64_t sys_xStreamBufferNextMessageLengthBytes(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) ( size_t ) xStreamBufferNextMessageLengthBytes((StreamBufferHandle_t) argptr[0]);
|
||||
}
|
||||
|
||||
uint64_t sys_xStreamBufferIsFull(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (BaseType_t) xStreamBufferIsFull((StreamBufferHandle_t) argptr[0]);
|
||||
}
|
||||
|
||||
uint64_t sys_xStreamBufferSpacesAvailable(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (size_t) xStreamBufferSpacesAvailable((StreamBufferHandle_t) argptr[0]);
|
||||
}
|
||||
|
||||
uint64_t sys_xStreamBufferReset(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (size_t) xStreamBufferReset((StreamBufferHandle_t) argptr[0]);
|
||||
}
|
||||
|
||||
|
||||
uint64_t sys_xStreamBufferBytesAvailable(uint64_t *argptr)
|
||||
{
|
||||
return (uint64_t) (size_t) xStreamBufferBytesAvailable((StreamBufferHandle_t) argptr[0]);
|
||||
}
|
||||
|
||||
extern StackType_t *pxCurrentTCB;
|
||||
void vInitSystemCall(void)
|
||||
{
|
||||
int i=0;
|
||||
for (i=0;i<MAX_SYSCALLS;i++) {
|
||||
system_calls[i] = NULL;
|
||||
}
|
||||
system_calls[SYSCALL_NUM_writec] = sys_writec;
|
||||
system_calls[SYSCALL_NUM_xTaskGetTickCount] = sys_xTaskGetTickCount;
|
||||
system_calls[SYSCALL_NUM_xTaskDelayUntil] = sys_xTaskDelayUntil;
|
||||
system_calls[SYSCALL_NUM_xQueueGenericSend] = sys_xQueueGenericSend;
|
||||
system_calls[SYSCALL_NUM_xQueueReceive] = sys_xQueueReceive;
|
||||
system_calls[SYSCALL_NUM_xTimerGenericCommandFromTask] = sys_xTimerGenericCommandFromTask;
|
||||
system_calls[SYSCALL_NUM_eTaskGetState]=sys_eTaskGetState;
|
||||
system_calls[SYSCALL_NUM_pcQueueGetName]=sys_pcQueueGetName;
|
||||
system_calls[SYSCALL_NUM_pcTimerGetName]=sys_pcTimerGetName;
|
||||
system_calls[SYSCALL_NUM_pvTimerGetTimerID]=sys_pvTimerGetTimerID;
|
||||
system_calls[SYSCALL_NUM_ulTaskGenericNotifyTake]=sys_ulTaskGenericNotifyTake;
|
||||
system_calls[SYSCALL_NUM_ulTaskGenericNotifyValueClear]=sys_ulTaskGenericNotifyValueClear;
|
||||
system_calls[SYSCALL_NUM_uxQueueMessagesWaiting]=sys_uxQueueMessagesWaiting;
|
||||
system_calls[SYSCALL_NUM_uxQueueSpacesAvailable]=sys_uxQueueSpacesAvailable;
|
||||
system_calls[SYSCALL_NUM_uxTaskGetNumberOfTasks]=sys_uxTaskGetNumberOfTasks;
|
||||
system_calls[SYSCALL_NUM_uxTaskGetSystemState]=sys_uxTaskGetSystemState;
|
||||
system_calls[SYSCALL_NUM_uxTaskPriorityGet]=sys_uxTaskPriorityGet;
|
||||
system_calls[SYSCALL_NUM_uxTimerGetReloadMode]=sys_uxTimerGetReloadMode;
|
||||
system_calls[SYSCALL_NUM_vQueueAddToRegistry]=sys_vQueueAddToRegistry;
|
||||
system_calls[SYSCALL_NUM_vQueueUnregisterQueue]=sys_vQueueUnregisterQueue;
|
||||
system_calls[SYSCALL_NUM_vTaskDelay]=sys_vTaskDelay;
|
||||
system_calls[SYSCALL_NUM_vTaskGetInfo]=sys_vTaskGetInfo;
|
||||
system_calls[SYSCALL_NUM_vTaskResume]=sys_vTaskResume;
|
||||
system_calls[SYSCALL_NUM_vTaskSetTimeOutState]=sys_vTaskSetTimeOutState;
|
||||
system_calls[SYSCALL_NUM_vTaskSuspend]=sys_vTaskSuspend;
|
||||
system_calls[SYSCALL_NUM_vTaskSuspendAll]=sys_vTaskSuspendAll;
|
||||
system_calls[SYSCALL_NUM_vTimerSetReloadMode]=sys_vTimerSetReloadMode;
|
||||
system_calls[SYSCALL_NUM_vTimerSetTimerID]=sys_vTimerSetTimerID;
|
||||
system_calls[SYSCALL_NUM_xQueueAddToSet]=sys_xQueueAddToSet;
|
||||
system_calls[SYSCALL_NUM_xQueueGiveMutexRecursive]=sys_xQueueGiveMutexRecursive;
|
||||
system_calls[SYSCALL_NUM_xQueuePeek]=sys_xQueuePeek;
|
||||
system_calls[SYSCALL_NUM_xQueueRemoveFromSet]=sys_xQueueRemoveFromSet;
|
||||
system_calls[SYSCALL_NUM_xQueueSelectFromSet]=sys_xQueueSelectFromSet;
|
||||
system_calls[SYSCALL_NUM_xQueueSemaphoreTake]=sys_xQueueSemaphoreTake;
|
||||
system_calls[SYSCALL_NUM_xQueueTakeMutexRecursive]=sys_xQueueTakeMutexRecursive;
|
||||
system_calls[SYSCALL_NUM_xTaskCheckForTimeOut]=sys_xTaskCheckForTimeOut;
|
||||
system_calls[SYSCALL_NUM_xTaskGenericNotify]=sys_xTaskGenericNotify;
|
||||
system_calls[SYSCALL_NUM_xTaskGenericNotifyStateClear]=sys_xTaskGenericNotifyStateClear;
|
||||
system_calls[SYSCALL_NUM_xTaskGenericNotifyWait]=sys_xTaskGenericNotifyWait;
|
||||
system_calls[SYSCALL_NUM_xTaskGetCurrentTaskHandle]=sys_xTaskGetCurrentTaskHandle;
|
||||
system_calls[SYSCALL_NUM_xTaskGetSchedulerState]=sys_xTaskGetSchedulerState;
|
||||
system_calls[SYSCALL_NUM_xTimerGetExpiryTime]=sys_xTimerGetExpiryTime;
|
||||
system_calls[SYSCALL_NUM_xTimerGetPeriod]=sys_xTimerGetPeriod;
|
||||
system_calls[SYSCALL_NUM_xTimerGetTimerDaemonTaskHandle]=sys_xTimerGetTimerDaemonTaskHandle;
|
||||
system_calls[SYSCALL_NUM_xTimerIsTimerActive]=sys_xTimerIsTimerActive;
|
||||
system_calls[SYSCALL_NUM_xTaskAbortDelay]=sys_xTaskAbortDelay;
|
||||
system_calls[SYSCALL_NUM_xTaskGetHandle]=sys_xTaskGetHandle;
|
||||
system_calls[SYSCALL_NUM_xEventGroupCreate]=sys_xEventGroupCreate;
|
||||
system_calls[SYSCALL_NUM_xEventGroupWaitBits]=sys_xEventGroupWaitBits;
|
||||
system_calls[SYSCALL_NUM_vEventGroupDelete]=sys_vEventGroupDelete;
|
||||
system_calls[SYSCALL_NUM_xStreamBufferGenericCreate]=sys_xStreamBufferGenericCreate;
|
||||
system_calls[SYSCALL_NUM_xStreamBufferReceive]=sys_xStreamBufferReceive;
|
||||
system_calls[SYSCALL_NUM_vStreamBufferDelete]=sys_vStreamBufferDelete;
|
||||
system_calls[SYSCALL_NUM_xQueueGetMutexHolder]=sys_xQueueGetMutexHolder;
|
||||
system_calls[SYSCALL_NUM_xEventGroupSync]=sys_xEventGroupSync;
|
||||
system_calls[SYSCALL_NUM_xEventGroupSetBits]=sys_xEventGroupSetBits;
|
||||
system_calls[SYSCALL_NUM_xEventGroupClearBits]=sys_xEventGroupClearBits;
|
||||
system_calls[SYSCALL_NUM_xStreamBufferSend]=sys_xStreamBufferSend;
|
||||
system_calls[SYSCALL_NUM_xStreamBufferIsEmpty]=sys_xStreamBufferIsEmpty;
|
||||
system_calls[SYSCALL_NUM_xStreamBufferNextMessageLengthBytes]=sys_xStreamBufferNextMessageLengthBytes;
|
||||
system_calls[SYSCALL_NUM_xStreamBufferIsFull]=sys_xStreamBufferIsFull;
|
||||
system_calls[SYSCALL_NUM_xStreamBufferSpacesAvailable]=sys_xStreamBufferSpacesAvailable;
|
||||
system_calls[SYSCALL_NUM_xStreamBufferReset]=sys_xStreamBufferReset;
|
||||
system_calls[SYSCALL_NUM_xStreamBufferBytesAvailable]=sys_xStreamBufferBytesAvailable;
|
||||
}
|
||||
|
||||
void vSystemCall(struct TrapFrame *tf)
|
||||
{
|
||||
int64_t i = tf->rax;
|
||||
int64_t param_count = tf->rdi;
|
||||
int64_t *argptr = (int64_t*)tf->rsi;
|
||||
|
||||
if (param_count < 0 || i >= MAX_SYSCALLS || i < 0) {
|
||||
tf->rax = -1;
|
||||
return;
|
||||
}
|
||||
if (system_calls[i]){
|
||||
tf->rax = system_calls[i](argptr);
|
||||
}
|
||||
else{
|
||||
tf->rax = -1;
|
||||
}
|
||||
}
|
||||
|
||||
183
portable/GCC/XEN_x86/x86-64/syscall.h
Normal file
183
portable/GCC/XEN_x86/x86-64/syscall.h
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
/* syscall
|
||||
*
|
||||
* Copyright (C) 2025 Advanced Micro Devices, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _SYSCALL_H_
|
||||
#define _SYSCALL_H_
|
||||
#include "FreeRTOS.h"
|
||||
#include "event_groups.h"
|
||||
#include "stream_buffer.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "timers.h"
|
||||
|
||||
|
||||
void syscall_writec(char val);
|
||||
BaseType_t syscall_xTaskGetTickCount(void);
|
||||
BaseType_t syscall_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
|
||||
TickType_t xTimeIncrement);
|
||||
BaseType_t syscall_xQueueGenericSend( QueueHandle_t xQueue,
|
||||
const void * const pvItemToQueue,
|
||||
TickType_t xTicksToWait,
|
||||
BaseType_t xCopyPosition );
|
||||
BaseType_t syscall_xQueueReceive( QueueHandle_t pxQueue,
|
||||
void * const pvBuffer,
|
||||
TickType_t xTicksToWait );
|
||||
BaseType_t syscall_xTimerGenericCommandFromTask( TimerHandle_t xTimer,
|
||||
const BaseType_t xCommandID,
|
||||
const TickType_t xOptionalValue,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||
const TickType_t xTicksToWait );
|
||||
QueueHandle_t syscall_xQueueGenericCreate( UBaseType_t uxQueueLength,
|
||||
UBaseType_t uxItemSize,
|
||||
uint8_t ucQueueType );
|
||||
BaseType_t syscall_xTaskCreate( TaskFunction_t pvTaskCode,
|
||||
const char * const pcName,
|
||||
const configSTACK_DEPTH_TYPE uxStackDepth,
|
||||
void * pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * pxCreatedTask );
|
||||
void syscall_vTaskDelete( TaskHandle_t pxTaskToDelete );
|
||||
void syscall_vTaskDelay( TickType_t xTicksToDelay );
|
||||
UBaseType_t syscall_uxTaskPriorityGet( const TaskHandle_t pxTask );
|
||||
void syscall_vTaskPrioritySet( TaskHandle_t pxTask,
|
||||
UBaseType_t uxNewPriority );
|
||||
eTaskState syscall_eTaskGetState( TaskHandle_t pxTask );
|
||||
void syscall_vTaskGetInfo( TaskHandle_t xTask,
|
||||
TaskStatus_t * pxTaskStatus,
|
||||
BaseType_t xGetFreeStackSpace,
|
||||
eTaskState eState );
|
||||
void syscall_vTaskSuspend( TaskHandle_t pxTaskToSuspend );
|
||||
void syscall_vTaskResume( TaskHandle_t pxTaskToResume );
|
||||
UBaseType_t syscall_uxTaskGetNumberOfTasks( void );
|
||||
UBaseType_t syscall_uxTaskGetSystemState( TaskStatus_t * pxTaskStatusArray,
|
||||
UBaseType_t uxArraySize,
|
||||
configRUN_TIME_COUNTER_TYPE * pulTotalRunTime );
|
||||
TaskHandle_t syscall_xTaskGetCurrentTaskHandle( void );
|
||||
BaseType_t syscall_xTaskGetSchedulerState( void );
|
||||
void syscall_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut );
|
||||
BaseType_t syscall_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,
|
||||
TickType_t * const pxTicksToWait );
|
||||
BaseType_t syscall_xTaskGenericNotify( TaskHandle_t xTaskToNotify,
|
||||
UBaseType_t uxIndexToNotify,
|
||||
uint32_t ulValue,
|
||||
eNotifyAction eAction,
|
||||
uint32_t * pulPreviousNotificationValue );
|
||||
BaseType_t syscall_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn,
|
||||
uint32_t ulBitsToClearOnEntry,
|
||||
uint32_t ulBitsToClearOnExit,
|
||||
uint32_t * pulNotificationValue,
|
||||
TickType_t xTicksToWait );
|
||||
uint32_t syscall_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn,
|
||||
BaseType_t xClearCountOnExit,
|
||||
TickType_t xTicksToWait );
|
||||
BaseType_t syscall_xTaskGenericNotifyStateClear( TaskHandle_t xTask,
|
||||
UBaseType_t uxIndexToClear );
|
||||
uint32_t syscall_ulTaskGenericNotifyValueClear( TaskHandle_t xTask,
|
||||
UBaseType_t uxIndexToClear,
|
||||
uint32_t ulBitsToClear );
|
||||
BaseType_t syscall_xQueueGenericReset( QueueHandle_t pxQueue,
|
||||
BaseType_t xNewQueue );
|
||||
UBaseType_t syscall_uxQueueMessagesWaiting( const QueueHandle_t pxQueue );
|
||||
UBaseType_t syscall_uxQueueSpacesAvailable( const QueueHandle_t xQueue );
|
||||
BaseType_t syscall_xQueuePeek( QueueHandle_t xQueue,
|
||||
void * const pvBuffer,
|
||||
TickType_t xTicksToWait );
|
||||
BaseType_t syscall_xQueueSemaphoreTake( QueueHandle_t xQueue,
|
||||
TickType_t xTicksToWait );
|
||||
QueueHandle_t syscall_xQueueCreateMutex( const uint8_t ucQueueType );
|
||||
QueueHandle_t syscall_xQueueCreateCountingSemaphore( UBaseType_t uxCountValue,
|
||||
UBaseType_t uxInitialCount );
|
||||
BaseType_t syscall_xQueueTakeMutexRecursive( QueueHandle_t xMutex,
|
||||
TickType_t xBlockTime );
|
||||
BaseType_t syscall_xQueueGiveMutexRecursive( QueueHandle_t xMutex );
|
||||
QueueSetHandle_t syscall_xQueueCreateSet( UBaseType_t uxEventQueueLength );
|
||||
QueueSetMemberHandle_t syscall_xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
|
||||
TickType_t xBlockTimeTicks );
|
||||
BaseType_t syscall_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
|
||||
QueueSetHandle_t xQueueSet );
|
||||
BaseType_t syscall_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
|
||||
QueueSetHandle_t xQueueSet );
|
||||
void syscall_vQueueAddToRegistry( QueueHandle_t xQueue,
|
||||
const char * pcName );
|
||||
void syscall_vQueueUnregisterQueue( QueueHandle_t xQueue );
|
||||
const char * syscall_pcQueueGetName( QueueHandle_t xQueue );
|
||||
void syscall_vQueueDelete( QueueHandle_t xQueue );
|
||||
void * syscall_pvTimerGetTimerID( const TimerHandle_t xTimer );
|
||||
void syscall_vTimerSetTimerID( TimerHandle_t xTimer,
|
||||
void * pvNewID );
|
||||
BaseType_t syscall_xTimerIsTimerActive( TimerHandle_t xTimer );
|
||||
TaskHandle_t syscall_xTimerGetTimerDaemonTaskHandle( void );
|
||||
void syscall_vTimerSetReloadMode( TimerHandle_t xTimer,
|
||||
const BaseType_t uxAutoReload );
|
||||
UBaseType_t syscall_uxTimerGetReloadMode( TimerHandle_t xTimer );
|
||||
const char * syscall_pcTimerGetName( TimerHandle_t xTimer );
|
||||
TickType_t syscall_xTimerGetPeriod( TimerHandle_t xTimer );
|
||||
TickType_t syscall_xTimerGetExpiryTime( TimerHandle_t xTimer );
|
||||
void syscall_vTaskListTasks( char * pcWriteBuffer,
|
||||
size_t uxBufferLength );
|
||||
void syscall_vTaskSuspendAll( void );
|
||||
BaseType_t syscall_xTaskResumeAll( void );
|
||||
BaseType_t syscall_xTaskAbortDelay( TaskHandle_t xTask );TaskHandle_t syscall_xTaskGetHandle( const char * pcNameToQuery );
|
||||
TaskHandle_t syscall_xTaskGetHandle( const char * pcNameToQuery );
|
||||
EventGroupHandle_t syscall_xEventGroupCreate( void ); /* FREERTOS_SYSTEM_CALL */
|
||||
EventBits_t syscall_xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
const BaseType_t xClearOnExit,
|
||||
const BaseType_t xWaitForAllBits,
|
||||
TickType_t xTicksToWait ); /* FREERTOS_SYSTEM_CALL */
|
||||
void syscall_vEventGroupDelete( EventGroupHandle_t xEventGroup ); /* FREERTOS_SYSTEM_CALL */
|
||||
StreamBufferHandle_t syscall_xStreamBufferGenericCreate( size_t xBufferSizeBytes,
|
||||
size_t xTriggerLevelBytes,
|
||||
BaseType_t xStreamBufferType,
|
||||
StreamBufferCallbackFunction_t pxSendCompletedCallback,
|
||||
StreamBufferCallbackFunction_t pxReceiveCompletedCallback ); /* FREERTOS_SYSTEM_CALL */
|
||||
size_t syscall_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||
void * pvRxData,
|
||||
size_t xBufferLengthBytes,
|
||||
TickType_t xTicksToWait ); /* FREERTOS_SYSTEM_CALL */
|
||||
void syscall_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ); /* FREERTOS_SYSTEM_CALL */
|
||||
TaskHandle_t syscall_xQueueGetMutexHolder( QueueHandle_t xSemaphore ); /* FREERTOS_SYSTEM_CALL */
|
||||
EventBits_t syscall_xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
TickType_t xTicksToWait ); /* FREERTOS_SYSTEM_CALL */
|
||||
EventBits_t syscall_xEventGroupSetBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet ); /* FREERTOS_SYSTEM_CALL */
|
||||
EventBits_t syscall_xEventGroupClearBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToClear ); /* FREERTOS_SYSTEM_CALL */
|
||||
size_t syscall_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||
const void * pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
TickType_t xTicksToWait ); /* FREERTOS_SYSTEM_CALL */
|
||||
BaseType_t syscall_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ); /* FREERTOS_SYSTEM_CALL */
|
||||
size_t syscall_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ); /* FREERTOS_SYSTEM_CALL */
|
||||
BaseType_t syscall_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ); /* FREERTOS_SYSTEM_CALL */
|
||||
size_t syscall_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ); /* FREERTOS_SYSTEM_CALL */
|
||||
BaseType_t syscall_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ); /* FREERTOS_SYSTEM_CALL */
|
||||
size_t syscall_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ); /* FREERTOS_SYSTEM_CALL */
|
||||
|
||||
|
||||
#endif
|
||||
439
portable/GCC/XEN_x86/x86-64/trap.c
Normal file
439
portable/GCC/XEN_x86/x86-64/trap.c
Normal file
|
|
@ -0,0 +1,439 @@
|
|||
/* trap
|
||||
*
|
||||
* Copyright (C) 2025 Advanced Micro Devices, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
#include "trap.h"
|
||||
#include "io.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "timers.h"
|
||||
#include "IRQ.h"
|
||||
#include "ioapic.h"
|
||||
#include "stdio.h"
|
||||
#include "hypervisor.h"
|
||||
#include "time.h"
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
void vSystemCall(struct TrapFrame *tf);
|
||||
void vInitSystemCall(void);
|
||||
void process_sci(void);
|
||||
void vFreeAllPages(uint64_t *p);
|
||||
|
||||
static struct IdtPtr idt_pointer;
|
||||
static struct IdtEntry vectors[256];
|
||||
extern uint64_t pml4;
|
||||
/* pxCurrentTCB saved by FreeRTOS Kernel */
|
||||
extern StackType_t *pxCurrentTCB;
|
||||
/* Tss defined in assembly files */
|
||||
extern struct TSS Tss;
|
||||
extern uint32_t ulPortYieldPending;
|
||||
extern uint32_t ulInterruptNesting;
|
||||
extern uint32_t xTaskUsesFPU;
|
||||
extern uint8_t *pucPortTaskFPUContextBuffer;
|
||||
|
||||
static void vInstallHandler(struct IdtEntry *entry, uint64_t addr, uint8_t attribute)
|
||||
{
|
||||
entry->low = (uint16_t)addr;
|
||||
entry->selector = 8;
|
||||
entry->attr = attribute;
|
||||
entry->mid = (uint16_t)(addr>>16);
|
||||
entry->high = (uint32_t)(addr>>32);
|
||||
}
|
||||
|
||||
void vIDTInit(void)
|
||||
{
|
||||
vInitSystemCall();
|
||||
vInstallHandler(&vectors[0],(uint64_t)vector0,0x8eUL);
|
||||
vInstallHandler(&vectors[1],(uint64_t)vector1,0x8eUL);
|
||||
vInstallHandler(&vectors[2],(uint64_t)vector2,0x8eUL);
|
||||
vInstallHandler(&vectors[3],(uint64_t)vector3,0x8eUL);
|
||||
vInstallHandler(&vectors[4],(uint64_t)vector4,0x8eUL);
|
||||
vInstallHandler(&vectors[5],(uint64_t)vector5,0x8eUL);
|
||||
vInstallHandler(&vectors[6],(uint64_t)vector6,0x8eUL);
|
||||
vInstallHandler(&vectors[7],(uint64_t)vector7,0x8eUL);
|
||||
vInstallHandler(&vectors[8],(uint64_t)vector8,0x8eUL);
|
||||
vInstallHandler(&vectors[10],(uint64_t)vector10,0x8eUL);
|
||||
vInstallHandler(&vectors[11],(uint64_t)vector11,0x8eUL);
|
||||
vInstallHandler(&vectors[12],(uint64_t)vector12,0x8eUL);
|
||||
vInstallHandler(&vectors[13],(uint64_t)vector13,0x8eUL);
|
||||
vInstallHandler(&vectors[14],(uint64_t)vector14,0x8eUL);
|
||||
vInstallHandler(&vectors[16],(uint64_t)vector16,0x8eUL);
|
||||
vInstallHandler(&vectors[17],(uint64_t)vector17,0x8eUL);
|
||||
vInstallHandler(&vectors[18],(uint64_t)vector18,0x8eUL);
|
||||
vInstallHandler(&vectors[19],(uint64_t)vector19,0x8eUL);
|
||||
vInstallHandler(&vectors[32],(uint64_t)vector32,0x8eUL);
|
||||
vInstallHandler(&vectors[33],(uint64_t)vector33,0x8eUL);
|
||||
vInstallHandler(&vectors[34],(uint64_t)vector34,0x8eUL);
|
||||
vInstallHandler(&vectors[35],(uint64_t)vector35,0x8eUL);
|
||||
vInstallHandler(&vectors[36],(uint64_t)vector36,0x8eUL);
|
||||
vInstallHandler(&vectors[37],(uint64_t)vector37,0x8eUL);
|
||||
vInstallHandler(&vectors[38],(uint64_t)vector38,0x8eUL);
|
||||
vInstallHandler(&vectors[39],(uint64_t)vector39,0x8eUL);
|
||||
vInstallHandler(&vectors[40],(uint64_t)vector40,0x8eUL);
|
||||
vInstallHandler(&vectors[41],(uint64_t)vector41,0x8eUL);
|
||||
vInstallHandler(&vectors[42],(uint64_t)vector42,0x8eUL);
|
||||
vInstallHandler(&vectors[43],(uint64_t)vector43,0x8eUL);
|
||||
vInstallHandler(&vectors[44],(uint64_t)vector44,0x8eUL);
|
||||
vInstallHandler(&vectors[45],(uint64_t)vector45,0x8eUL);
|
||||
vInstallHandler(&vectors[46],(uint64_t)vector46,0x8eUL);
|
||||
vInstallHandler(&vectors[47],(uint64_t)vector47,0x8eUL);
|
||||
vInstallHandler(&vectors[48],(uint64_t)vector48,0x8eUL);
|
||||
vInstallHandler(&vectors[49],(uint64_t)vector49,0x8eUL);
|
||||
vInstallHandler(&vectors[50],(uint64_t)vector50,0x8eUL);
|
||||
vInstallHandler(&vectors[51],(uint64_t)vector51,0x8eUL);
|
||||
vInstallHandler(&vectors[52],(uint64_t)vector52,0x8eUL);
|
||||
vInstallHandler(&vectors[53],(uint64_t)vector53,0x8eUL);
|
||||
vInstallHandler(&vectors[54],(uint64_t)vector54,0x8eUL);
|
||||
vInstallHandler(&vectors[55],(uint64_t)vector55,0x8eUL);
|
||||
vInstallHandler(&vectors[56],(uint64_t)vector56,0x8eUL);
|
||||
vInstallHandler(&vectors[57],(uint64_t)vector57,0x8eUL);
|
||||
vInstallHandler(&vectors[58],(uint64_t)vector58,0x8eUL);
|
||||
vInstallHandler(&vectors[59],(uint64_t)vector59,0x8eUL);
|
||||
vInstallHandler(&vectors[60],(uint64_t)vector60,0x8eUL);
|
||||
vInstallHandler(&vectors[61],(uint64_t)vector61,0x8eUL);
|
||||
vInstallHandler(&vectors[62],(uint64_t)vector62,0x8eUL);
|
||||
vInstallHandler(&vectors[63],(uint64_t)vector63,0x8eUL);
|
||||
vInstallHandler(&vectors[64],(uint64_t)vector64,0x8eUL);
|
||||
vInstallHandler(&vectors[65],(uint64_t)vector65,0x8eUL);
|
||||
vInstallHandler(&vectors[66],(uint64_t)vector66,0x8eUL);
|
||||
vInstallHandler(&vectors[67],(uint64_t)vector67,0x8eUL);
|
||||
vInstallHandler(&vectors[68],(uint64_t)vector68,0x8eUL);
|
||||
vInstallHandler(&vectors[69],(uint64_t)vector69,0x8eUL);
|
||||
vInstallHandler(&vectors[70],(uint64_t)vector70,0x8eUL);
|
||||
vInstallHandler(&vectors[71],(uint64_t)vector71,0x8eUL);
|
||||
vInstallHandler(&vectors[72],(uint64_t)vector72,0x8eUL);
|
||||
vInstallHandler(&vectors[73],(uint64_t)vector73,0x8eUL);
|
||||
vInstallHandler(&vectors[74],(uint64_t)vector74,0x8eUL);
|
||||
vInstallHandler(&vectors[75],(uint64_t)vector75,0x8eUL);
|
||||
vInstallHandler(&vectors[76],(uint64_t)vector76,0x8eUL);
|
||||
vInstallHandler(&vectors[77],(uint64_t)vector77,0x8eUL);
|
||||
vInstallHandler(&vectors[78],(uint64_t)vector78,0x8eUL);
|
||||
vInstallHandler(&vectors[79],(uint64_t)vector79,0x8eUL);
|
||||
vInstallHandler(&vectors[80],(uint64_t)vector80,0x8eUL);
|
||||
vInstallHandler(&vectors[81],(uint64_t)vector81,0x8eUL);
|
||||
vInstallHandler(&vectors[82],(uint64_t)vector82,0x8eUL);
|
||||
vInstallHandler(&vectors[83],(uint64_t)vector83,0x8eUL);
|
||||
vInstallHandler(&vectors[84],(uint64_t)vector84,0x8eUL);
|
||||
vInstallHandler(&vectors[85],(uint64_t)vector85,0x8eUL);
|
||||
vInstallHandler(&vectors[86],(uint64_t)vector86,0x8eUL);
|
||||
vInstallHandler(&vectors[87],(uint64_t)vector87,0x8eUL);
|
||||
vInstallHandler(&vectors[88],(uint64_t)vector88,0x8eUL);
|
||||
vInstallHandler(&vectors[89],(uint64_t)vector89,0x8eUL);
|
||||
vInstallHandler(&vectors[90],(uint64_t)vector90,0x8eUL);
|
||||
vInstallHandler(&vectors[91],(uint64_t)vector91,0x8eUL);
|
||||
vInstallHandler(&vectors[92],(uint64_t)vector92,0x8eUL);
|
||||
vInstallHandler(&vectors[93],(uint64_t)vector93,0x8eUL);
|
||||
vInstallHandler(&vectors[94],(uint64_t)vector94,0x8eUL);
|
||||
vInstallHandler(&vectors[95],(uint64_t)vector95,0x8eUL);
|
||||
vInstallHandler(&vectors[96],(uint64_t)vector96,0x8eUL);
|
||||
vInstallHandler(&vectors[97],(uint64_t)vector97,0x8eUL);
|
||||
vInstallHandler(&vectors[98],(uint64_t)vector98,0x8eUL);
|
||||
vInstallHandler(&vectors[99],(uint64_t)vector99,0x8eUL);
|
||||
vInstallHandler(&vectors[100],(uint64_t)vector100,0x8eUL);
|
||||
vInstallHandler(&vectors[101],(uint64_t)vector101,0x8eUL);
|
||||
vInstallHandler(&vectors[102],(uint64_t)vector102,0x8eUL);
|
||||
vInstallHandler(&vectors[103],(uint64_t)vector103,0x8eUL);
|
||||
vInstallHandler(&vectors[104],(uint64_t)vector104,0x8eUL);
|
||||
vInstallHandler(&vectors[105],(uint64_t)vector105,0x8eUL);
|
||||
vInstallHandler(&vectors[106],(uint64_t)vector106,0x8eUL);
|
||||
vInstallHandler(&vectors[107],(uint64_t)vector107,0x8eUL);
|
||||
vInstallHandler(&vectors[108],(uint64_t)vector108,0x8eUL);
|
||||
vInstallHandler(&vectors[109],(uint64_t)vector109,0x8eUL);
|
||||
vInstallHandler(&vectors[110],(uint64_t)vector110,0x8eUL);
|
||||
vInstallHandler(&vectors[111],(uint64_t)vector111,0x8eUL);
|
||||
vInstallHandler(&vectors[112],(uint64_t)vector112,0x8eUL);
|
||||
vInstallHandler(&vectors[113],(uint64_t)vector113,0x8eUL);
|
||||
vInstallHandler(&vectors[114],(uint64_t)vector114,0x8eUL);
|
||||
vInstallHandler(&vectors[115],(uint64_t)vector115,0x8eUL);
|
||||
vInstallHandler(&vectors[116],(uint64_t)vector116,0x8eUL);
|
||||
vInstallHandler(&vectors[117],(uint64_t)vector117,0x8eUL);
|
||||
vInstallHandler(&vectors[118],(uint64_t)vector118,0x8eUL);
|
||||
vInstallHandler(&vectors[119],(uint64_t)vector119,0x8eUL);
|
||||
vInstallHandler(&vectors[120],(uint64_t)vector120,0x8eUL);
|
||||
vInstallHandler(&vectors[121],(uint64_t)vector121,0x8eUL);
|
||||
vInstallHandler(&vectors[122],(uint64_t)vector122,0x8eUL);
|
||||
vInstallHandler(&vectors[123],(uint64_t)vector123,0x8eUL);
|
||||
vInstallHandler(&vectors[124],(uint64_t)vector124,0x8eUL);
|
||||
vInstallHandler(&vectors[125],(uint64_t)vector125,0x8eUL);
|
||||
vInstallHandler(&vectors[126],(uint64_t)vector126,0x8eUL);
|
||||
vInstallHandler(&vectors[127],(uint64_t)vector127,0x8eUL);
|
||||
vInstallHandler(&vectors[129],(uint64_t)vector129,0x8eUL);
|
||||
vInstallHandler(&vectors[130],(uint64_t)vector130,0x8eUL);
|
||||
vInstallHandler(&vectors[131],(uint64_t)vector131,0x8eUL);
|
||||
vInstallHandler(&vectors[132],(uint64_t)vector132,0x8eUL);
|
||||
vInstallHandler(&vectors[133],(uint64_t)vector133,0x8eUL);
|
||||
vInstallHandler(&vectors[134],(uint64_t)vector134,0x8eUL);
|
||||
vInstallHandler(&vectors[135],(uint64_t)vector135,0x8eUL);
|
||||
vInstallHandler(&vectors[136],(uint64_t)vector136,0x8eUL);
|
||||
vInstallHandler(&vectors[137],(uint64_t)vector137,0x8eUL);
|
||||
vInstallHandler(&vectors[138],(uint64_t)vector138,0x8eUL);
|
||||
vInstallHandler(&vectors[139],(uint64_t)vector139,0x8eUL);
|
||||
vInstallHandler(&vectors[140],(uint64_t)vector140,0x8eUL);
|
||||
vInstallHandler(&vectors[141],(uint64_t)vector141,0x8eUL);
|
||||
vInstallHandler(&vectors[142],(uint64_t)vector142,0x8eUL);
|
||||
vInstallHandler(&vectors[143],(uint64_t)vector143,0x8eUL);
|
||||
vInstallHandler(&vectors[144],(uint64_t)vector144,0x8eUL);
|
||||
vInstallHandler(&vectors[145],(uint64_t)vector145,0x8eUL);
|
||||
vInstallHandler(&vectors[146],(uint64_t)vector146,0x8eUL);
|
||||
vInstallHandler(&vectors[147],(uint64_t)vector147,0x8eUL);
|
||||
vInstallHandler(&vectors[148],(uint64_t)vector148,0x8eUL);
|
||||
vInstallHandler(&vectors[149],(uint64_t)vector149,0x8eUL);
|
||||
vInstallHandler(&vectors[150],(uint64_t)vector150,0x8eUL);
|
||||
vInstallHandler(&vectors[151],(uint64_t)vector151,0x8eUL);
|
||||
vInstallHandler(&vectors[152],(uint64_t)vector152,0x8eUL);
|
||||
vInstallHandler(&vectors[153],(uint64_t)vector153,0x8eUL);
|
||||
vInstallHandler(&vectors[154],(uint64_t)vector154,0x8eUL);
|
||||
vInstallHandler(&vectors[155],(uint64_t)vector155,0x8eUL);
|
||||
vInstallHandler(&vectors[156],(uint64_t)vector156,0x8eUL);
|
||||
vInstallHandler(&vectors[157],(uint64_t)vector157,0x8eUL);
|
||||
vInstallHandler(&vectors[158],(uint64_t)vector158,0x8eUL);
|
||||
vInstallHandler(&vectors[159],(uint64_t)vector159,0x8eUL);
|
||||
vInstallHandler(&vectors[160],(uint64_t)vector160,0x8eUL);
|
||||
vInstallHandler(&vectors[161],(uint64_t)vector161,0x8eUL);
|
||||
vInstallHandler(&vectors[162],(uint64_t)vector162,0x8eUL);
|
||||
vInstallHandler(&vectors[163],(uint64_t)vector163,0x8eUL);
|
||||
vInstallHandler(&vectors[164],(uint64_t)vector164,0x8eUL);
|
||||
vInstallHandler(&vectors[165],(uint64_t)vector165,0x8eUL);
|
||||
vInstallHandler(&vectors[166],(uint64_t)vector166,0x8eUL);
|
||||
vInstallHandler(&vectors[167],(uint64_t)vector167,0x8eUL);
|
||||
vInstallHandler(&vectors[168],(uint64_t)vector168,0x8eUL);
|
||||
vInstallHandler(&vectors[169],(uint64_t)vector169,0x8eUL);
|
||||
vInstallHandler(&vectors[170],(uint64_t)vector170,0x8eUL);
|
||||
vInstallHandler(&vectors[171],(uint64_t)vector171,0x8eUL);
|
||||
vInstallHandler(&vectors[172],(uint64_t)vector172,0x8eUL);
|
||||
vInstallHandler(&vectors[173],(uint64_t)vector173,0x8eUL);
|
||||
vInstallHandler(&vectors[174],(uint64_t)vector174,0x8eUL);
|
||||
vInstallHandler(&vectors[175],(uint64_t)vector175,0x8eUL);
|
||||
vInstallHandler(&vectors[176],(uint64_t)vector176,0x8eUL);
|
||||
vInstallHandler(&vectors[177],(uint64_t)vector177,0x8eUL);
|
||||
vInstallHandler(&vectors[178],(uint64_t)vector178,0x8eUL);
|
||||
vInstallHandler(&vectors[179],(uint64_t)vector179,0x8eUL);
|
||||
vInstallHandler(&vectors[180],(uint64_t)vector180,0x8eUL);
|
||||
vInstallHandler(&vectors[181],(uint64_t)vector181,0x8eUL);
|
||||
vInstallHandler(&vectors[182],(uint64_t)vector182,0x8eUL);
|
||||
vInstallHandler(&vectors[183],(uint64_t)vector183,0x8eUL);
|
||||
vInstallHandler(&vectors[184],(uint64_t)vector184,0x8eUL);
|
||||
vInstallHandler(&vectors[185],(uint64_t)vector185,0x8eUL);
|
||||
vInstallHandler(&vectors[186],(uint64_t)vector186,0x8eUL);
|
||||
vInstallHandler(&vectors[187],(uint64_t)vector187,0x8eUL);
|
||||
vInstallHandler(&vectors[188],(uint64_t)vector188,0x8eUL);
|
||||
vInstallHandler(&vectors[189],(uint64_t)vector189,0x8eUL);
|
||||
vInstallHandler(&vectors[190],(uint64_t)vector190,0x8eUL);
|
||||
vInstallHandler(&vectors[191],(uint64_t)vector191,0x8eUL);
|
||||
vInstallHandler(&vectors[192],(uint64_t)vector192,0x8eUL);
|
||||
vInstallHandler(&vectors[193],(uint64_t)vector193,0x8eUL);
|
||||
vInstallHandler(&vectors[194],(uint64_t)vector194,0x8eUL);
|
||||
vInstallHandler(&vectors[195],(uint64_t)vector195,0x8eUL);
|
||||
vInstallHandler(&vectors[196],(uint64_t)vector196,0x8eUL);
|
||||
vInstallHandler(&vectors[197],(uint64_t)vector197,0x8eUL);
|
||||
vInstallHandler(&vectors[198],(uint64_t)vector198,0x8eUL);
|
||||
vInstallHandler(&vectors[199],(uint64_t)vector199,0x8eUL);
|
||||
vInstallHandler(&vectors[200],(uint64_t)vector200,0x8eUL);
|
||||
vInstallHandler(&vectors[201],(uint64_t)vector201,0x8eUL);
|
||||
vInstallHandler(&vectors[202],(uint64_t)vector202,0x8eUL);
|
||||
vInstallHandler(&vectors[203],(uint64_t)vector203,0x8eUL);
|
||||
vInstallHandler(&vectors[204],(uint64_t)vector204,0x8eUL);
|
||||
vInstallHandler(&vectors[205],(uint64_t)vector205,0x8eUL);
|
||||
vInstallHandler(&vectors[206],(uint64_t)vector206,0x8eUL);
|
||||
vInstallHandler(&vectors[207],(uint64_t)vector207,0x8eUL);
|
||||
vInstallHandler(&vectors[208],(uint64_t)vector208,0x8eUL);
|
||||
vInstallHandler(&vectors[209],(uint64_t)vector209,0x8eUL);
|
||||
vInstallHandler(&vectors[210],(uint64_t)vector210,0x8eUL);
|
||||
vInstallHandler(&vectors[211],(uint64_t)vector211,0x8eUL);
|
||||
vInstallHandler(&vectors[212],(uint64_t)vector212,0x8eUL);
|
||||
vInstallHandler(&vectors[213],(uint64_t)vector213,0x8eUL);
|
||||
vInstallHandler(&vectors[214],(uint64_t)vector214,0x8eUL);
|
||||
vInstallHandler(&vectors[215],(uint64_t)vector215,0x8eUL);
|
||||
vInstallHandler(&vectors[216],(uint64_t)vector216,0x8eUL);
|
||||
vInstallHandler(&vectors[217],(uint64_t)vector217,0x8eUL);
|
||||
vInstallHandler(&vectors[218],(uint64_t)vector218,0x8eUL);
|
||||
vInstallHandler(&vectors[219],(uint64_t)vector219,0x8eUL);
|
||||
vInstallHandler(&vectors[220],(uint64_t)vector220,0x8eUL);
|
||||
vInstallHandler(&vectors[221],(uint64_t)vector221,0x8eUL);
|
||||
vInstallHandler(&vectors[222],(uint64_t)vector222,0x8eUL);
|
||||
vInstallHandler(&vectors[223],(uint64_t)vector223,0x8eUL);
|
||||
vInstallHandler(&vectors[224],(uint64_t)vector224,0x8eUL);
|
||||
vInstallHandler(&vectors[225],(uint64_t)vector225,0x8eUL);
|
||||
vInstallHandler(&vectors[226],(uint64_t)vector226,0x8eUL);
|
||||
vInstallHandler(&vectors[227],(uint64_t)vector227,0x8eUL);
|
||||
vInstallHandler(&vectors[228],(uint64_t)vector228,0x8eUL);
|
||||
vInstallHandler(&vectors[229],(uint64_t)vector229,0x8eUL);
|
||||
vInstallHandler(&vectors[230],(uint64_t)vector230,0x8eUL);
|
||||
vInstallHandler(&vectors[231],(uint64_t)vector231,0x8eUL);
|
||||
vInstallHandler(&vectors[232],(uint64_t)vector232,0x8eUL);
|
||||
vInstallHandler(&vectors[233],(uint64_t)vector233,0x8eUL);
|
||||
vInstallHandler(&vectors[234],(uint64_t)vector234,0x8eUL);
|
||||
vInstallHandler(&vectors[235],(uint64_t)vector235,0x8eUL);
|
||||
vInstallHandler(&vectors[236],(uint64_t)vector236,0x8eUL);
|
||||
vInstallHandler(&vectors[237],(uint64_t)vector237,0x8eUL);
|
||||
vInstallHandler(&vectors[238],(uint64_t)vector238,0x8eUL);
|
||||
vInstallHandler(&vectors[239],(uint64_t)vector239,0x8eUL);
|
||||
vInstallHandler(&vectors[240],(uint64_t)vector240,0x8eUL);
|
||||
vInstallHandler(&vectors[241],(uint64_t)vector241,0x8eUL);
|
||||
vInstallHandler(&vectors[242],(uint64_t)vector242,0x8eUL);
|
||||
vInstallHandler(&vectors[243],(uint64_t)vector243,0x8eUL);
|
||||
vInstallHandler(&vectors[244],(uint64_t)vector244,0x8eUL);
|
||||
vInstallHandler(&vectors[245],(uint64_t)vector245,0x8eUL);
|
||||
vInstallHandler(&vectors[246],(uint64_t)vector246,0x8eUL);
|
||||
vInstallHandler(&vectors[247],(uint64_t)vector247,0x8eUL);
|
||||
vInstallHandler(&vectors[248],(uint64_t)vector248,0x8eUL);
|
||||
vInstallHandler(&vectors[249],(uint64_t)vector249,0x8eUL);
|
||||
vInstallHandler(&vectors[250],(uint64_t)vector250,0x8eUL);
|
||||
vInstallHandler(&vectors[251],(uint64_t)vector251,0x8eUL);
|
||||
vInstallHandler(&vectors[252],(uint64_t)vector252,0x8eUL);
|
||||
vInstallHandler(&vectors[253],(uint64_t)vector253,0x8eUL);
|
||||
vInstallHandler(&vectors[0x80],(uint64_t)sysint,0xeeUL);
|
||||
vInstallHandler(&vectors[254],(uint64_t)vector254,0xeeUL);
|
||||
vInstallHandler(&vectors[255],(uint64_t)vector255,0xeeUL);
|
||||
|
||||
idt_pointer.limit = sizeof(vectors)-1;
|
||||
idt_pointer.addr = (uint64_t)vectors;
|
||||
load_idt(&idt_pointer);
|
||||
init_irq_handlers();
|
||||
}
|
||||
|
||||
static void vScheduleTCB(StackType_t **nextTCB) {
|
||||
struct TrapFrame *tf = (struct TrapFrame *)(*nextTCB);
|
||||
xMPU_SETTINGS * xMPUSettings = (xMPU_SETTINGS *) (nextTCB+1);
|
||||
Tss.rsp0 = (uint64_t) xMPUSettings->kernel_stack;
|
||||
load_cr3(xMPUSettings->pgd);
|
||||
starttask(*nextTCB);
|
||||
}
|
||||
|
||||
static void vYieldHandler(struct TrapFrame *tf)
|
||||
{
|
||||
StackType_t **prevTCB = (StackType_t **) pxCurrentTCB;
|
||||
*prevTCB = (StackType_t *) tf;
|
||||
vTaskSwitchContext();
|
||||
StackType_t **nextTCB = (StackType_t **)pxCurrentTCB;
|
||||
if (nextTCB != prevTCB) {
|
||||
vScheduleTCB(nextTCB);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void vTimerHandler(struct TrapFrame *tf)
|
||||
{
|
||||
if (pxCurrentTCB !=NULL) {
|
||||
StackType_t **prevTCB = (StackType_t **)pxCurrentTCB;
|
||||
BaseType_t rc = xTaskIncrementTick();
|
||||
if (rc == pdTRUE) {
|
||||
vTaskSwitchContext();
|
||||
StackType_t **nextTCB = (StackType_t **)pxCurrentTCB;
|
||||
if (prevTCB != nextTCB) {
|
||||
*prevTCB = (StackType_t *) tf;
|
||||
eoi();
|
||||
vScheduleTCB(nextTCB);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vHandler(struct TrapFrame *tf)
|
||||
{
|
||||
unsigned char isr_value;
|
||||
|
||||
switch (tf->trapno) {
|
||||
case TRAP_YIELD:
|
||||
{
|
||||
vYieldHandler(tf);
|
||||
break;
|
||||
}
|
||||
|
||||
case TRAP_PIC_TIMER:
|
||||
eoi();
|
||||
break;
|
||||
|
||||
case TRAP_HYPERVISOR_EVENT:
|
||||
do_hypervisor_callback(0);
|
||||
eoi();
|
||||
break;
|
||||
|
||||
case TRAP_SPURIOUS:
|
||||
isr_value = read_isr();
|
||||
if ((isr_value&(1<<7)) != 0) {
|
||||
eoi();
|
||||
}
|
||||
break;
|
||||
|
||||
case TRAP_SCI:
|
||||
{
|
||||
process_sci();
|
||||
eoi();
|
||||
break;
|
||||
}
|
||||
|
||||
case TRAP_TIMER:
|
||||
{
|
||||
vTimerHandler(tf);
|
||||
eoi();
|
||||
break;
|
||||
}
|
||||
|
||||
case TRAP_SYSCALL:
|
||||
vSystemCall(tf);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (tf->trapno > TRAP_PIC_TIMER) {
|
||||
if ( (ulInterruptNesting == (uint32_t)0) && xTaskUsesFPU) {
|
||||
asm volatile(" fxsave %0 "::"m"(pucPortTaskFPUContextBuffer));
|
||||
}
|
||||
ulInterruptNesting++;
|
||||
uint32_t irq = tf->trapno - TRAP_PIC_TIMER;
|
||||
INT_HANDLER irq_handler = get_int_handler(irq);
|
||||
if (irq_handler != NULL) {
|
||||
irq_handler();
|
||||
}
|
||||
eoi();
|
||||
ulInterruptNesting--;
|
||||
if ( (ulInterruptNesting == (uint32_t)0) && xTaskUsesFPU) {
|
||||
asm volatile(" fxrstor %0 "::"m"(pucPortTaskFPUContextBuffer));
|
||||
}
|
||||
if ((ulInterruptNesting ==(uint32_t) 0) && ulPortYieldPending) {
|
||||
ulPortYieldPending = 0;
|
||||
vYieldHandler(tf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
printk("\n[Error %d at ring %d] errorcode:%d cr2:%p rflags: %p ss:%p\n", tf->trapno, (tf->cs & 3), tf->errorcode, read_cr2(),tf->rflags,tf->ss);
|
||||
printk("Registers:rip=%p rsp=%p rbp=%p\n", tf->rip, tf->rsp, tf->rbp);
|
||||
printk("Registers:rax=%p rbx=%p rcx=%p rdx=%p rsi=%p rdi=%p\n", tf->rax,tf->rbx,tf->rcx,tf->rdx,tf->rsi,tf->rdi);
|
||||
printk("Registers:r8=%p r9=%p r10=%p r11=%p r12=%p r13=%p r14=%p r15=%p\n", tf->r8,tf->r9,tf->r10,tf->r11,tf->r12,tf->r13,tf->r14,tf->r15);
|
||||
if ((tf->cs & 3) != 0) {
|
||||
xMPU_SETTINGS * xMPUSettings = (xMPU_SETTINGS *) (pxCurrentTCB+1);
|
||||
Tss.rsp0 = (uint64_t) xMPUSettings->kernel_stack;
|
||||
vFreeAllPages((uint64_t *) xMPUSettings->pgd);
|
||||
load_cr3(&pml4);
|
||||
eoi();
|
||||
vTaskDelete((TaskHandle_t)pxCurrentTCB);
|
||||
}
|
||||
vAssertCalled(__FILE__,__LINE__);
|
||||
}
|
||||
|
||||
}
|
||||
372
portable/GCC/XEN_x86/x86-64/trap.h
Normal file
372
portable/GCC/XEN_x86/x86-64/trap.h
Normal file
|
|
@ -0,0 +1,372 @@
|
|||
/* trap
|
||||
*
|
||||
* Copyright (C) 2025 Advanced Micro Devices, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _TRAP_H_
|
||||
#define _TRAP_H_
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
#define TRAP_PIC_TIMER 32
|
||||
#define TRAP_YIELD 33
|
||||
#define TRAP_HYPERVISOR_EVENT 37
|
||||
#define TRAP_SPURIOUS 39
|
||||
#define TRAP_SCI 41
|
||||
#define TRAP_TIMER 50
|
||||
#define TRAP_SYSCALL 128
|
||||
|
||||
typedef uint64_t (*SYSTEMCALL)(uint64_t *argptr);
|
||||
|
||||
struct TSS {
|
||||
uint32_t res0;
|
||||
uint64_t rsp0;
|
||||
uint64_t rsp1;
|
||||
uint64_t rsp2;
|
||||
uint64_t res1;
|
||||
uint64_t ist1;
|
||||
uint64_t ist2;
|
||||
uint64_t ist3;
|
||||
uint64_t ist4;
|
||||
uint64_t ist5;
|
||||
uint64_t ist6;
|
||||
uint64_t ist7;
|
||||
uint64_t res2;
|
||||
uint16_t res3;
|
||||
uint16_t iopb;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct IdtEntry{
|
||||
uint16_t low;
|
||||
uint16_t selector;
|
||||
uint8_t res0;
|
||||
uint8_t attr;
|
||||
uint16_t mid;
|
||||
uint32_t high;
|
||||
uint32_t res1;
|
||||
};
|
||||
|
||||
struct IdtPtr {
|
||||
uint16_t limit;
|
||||
uint64_t addr;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct TrapFrame {
|
||||
int64_t r15;
|
||||
int64_t r14;
|
||||
int64_t r13;
|
||||
int64_t r12;
|
||||
int64_t r11;
|
||||
int64_t r10;
|
||||
int64_t r9;
|
||||
int64_t r8;
|
||||
int64_t rbp;
|
||||
int64_t rdi;
|
||||
int64_t rsi;
|
||||
int64_t rdx;
|
||||
int64_t rcx;
|
||||
int64_t rbx;
|
||||
int64_t rax;
|
||||
int64_t trapno;
|
||||
int64_t errorcode;
|
||||
int64_t rip;
|
||||
int64_t cs;
|
||||
int64_t rflags;
|
||||
int64_t rsp;
|
||||
int64_t ss;
|
||||
};
|
||||
|
||||
static inline void eoi(void) {
|
||||
*(volatile unsigned int*)0xFEE000B0 = 0x0;
|
||||
}
|
||||
|
||||
void sysint(void);
|
||||
void vIDTInit(void);
|
||||
void load_idt(struct IdtPtr *ptr);
|
||||
unsigned char read_isr(void);
|
||||
uint64_t read_cr2(void);
|
||||
void TrapReturn(void);
|
||||
uint64_t load_cr3();
|
||||
void send_char_to_cli();
|
||||
void starttask(void *);
|
||||
|
||||
void vector0(void);
|
||||
void vector1(void);
|
||||
void vector2(void);
|
||||
void vector3(void);
|
||||
void vector4(void);
|
||||
void vector5(void);
|
||||
void vector6(void);
|
||||
void vector7(void);
|
||||
void vector8(void);
|
||||
void vector9(void);
|
||||
void vector10(void);
|
||||
void vector11(void);
|
||||
void vector12(void);
|
||||
void vector13(void);
|
||||
void vector14(void);
|
||||
void vector15(void);
|
||||
void vector16(void);
|
||||
void vector17(void);
|
||||
void vector18(void);
|
||||
void vector19(void);
|
||||
void vector20(void);
|
||||
void vector21(void);
|
||||
void vector22(void);
|
||||
void vector23(void);
|
||||
void vector24(void);
|
||||
void vector25(void);
|
||||
void vector26(void);
|
||||
void vector27(void);
|
||||
void vector28(void);
|
||||
void vector29(void);
|
||||
void vector30(void);
|
||||
void vector31(void);
|
||||
void vector32(void);
|
||||
void vector33(void);
|
||||
void vector34(void);
|
||||
void vector35(void);
|
||||
void vector36(void);
|
||||
void vector37(void);
|
||||
void vector38(void);
|
||||
void vector39(void);
|
||||
void vector40(void);
|
||||
void vector41(void);
|
||||
void vector42(void);
|
||||
void vector43(void);
|
||||
void vector44(void);
|
||||
void vector45(void);
|
||||
void vector46(void);
|
||||
void vector47(void);
|
||||
void vector48(void);
|
||||
void vector49(void);
|
||||
void vector50(void);
|
||||
void vector51(void);
|
||||
void vector52(void);
|
||||
void vector53(void);
|
||||
void vector54(void);
|
||||
void vector55(void);
|
||||
void vector56(void);
|
||||
void vector57(void);
|
||||
void vector58(void);
|
||||
void vector59(void);
|
||||
void vector60(void);
|
||||
void vector61(void);
|
||||
void vector62(void);
|
||||
void vector63(void);
|
||||
void vector64(void);
|
||||
void vector65(void);
|
||||
void vector66(void);
|
||||
void vector67(void);
|
||||
void vector68(void);
|
||||
void vector69(void);
|
||||
void vector70(void);
|
||||
void vector71(void);
|
||||
void vector72(void);
|
||||
void vector73(void);
|
||||
void vector74(void);
|
||||
void vector75(void);
|
||||
void vector76(void);
|
||||
void vector77(void);
|
||||
void vector78(void);
|
||||
void vector79(void);
|
||||
void vector80(void);
|
||||
void vector81(void);
|
||||
void vector82(void);
|
||||
void vector83(void);
|
||||
void vector84(void);
|
||||
void vector85(void);
|
||||
void vector86(void);
|
||||
void vector87(void);
|
||||
void vector88(void);
|
||||
void vector89(void);
|
||||
void vector90(void);
|
||||
void vector91(void);
|
||||
void vector92(void);
|
||||
void vector93(void);
|
||||
void vector94(void);
|
||||
void vector95(void);
|
||||
void vector96(void);
|
||||
void vector97(void);
|
||||
void vector98(void);
|
||||
void vector99(void);
|
||||
void vector100(void);
|
||||
void vector101(void);
|
||||
void vector102(void);
|
||||
void vector103(void);
|
||||
void vector104(void);
|
||||
void vector105(void);
|
||||
void vector106(void);
|
||||
void vector107(void);
|
||||
void vector108(void);
|
||||
void vector109(void);
|
||||
void vector110(void);
|
||||
void vector111(void);
|
||||
void vector112(void);
|
||||
void vector113(void);
|
||||
void vector114(void);
|
||||
void vector115(void);
|
||||
void vector116(void);
|
||||
void vector117(void);
|
||||
void vector118(void);
|
||||
void vector119(void);
|
||||
void vector120(void);
|
||||
void vector121(void);
|
||||
void vector122(void);
|
||||
void vector123(void);
|
||||
void vector124(void);
|
||||
void vector125(void);
|
||||
void vector126(void);
|
||||
void vector127(void);
|
||||
void vector128(void);
|
||||
void vector129(void);
|
||||
void vector130(void);
|
||||
void vector131(void);
|
||||
void vector132(void);
|
||||
void vector133(void);
|
||||
void vector134(void);
|
||||
void vector135(void);
|
||||
void vector136(void);
|
||||
void vector137(void);
|
||||
void vector138(void);
|
||||
void vector139(void);
|
||||
void vector140(void);
|
||||
void vector141(void);
|
||||
void vector142(void);
|
||||
void vector143(void);
|
||||
void vector144(void);
|
||||
void vector145(void);
|
||||
void vector146(void);
|
||||
void vector147(void);
|
||||
void vector148(void);
|
||||
void vector149(void);
|
||||
void vector150(void);
|
||||
void vector151(void);
|
||||
void vector152(void);
|
||||
void vector153(void);
|
||||
void vector154(void);
|
||||
void vector155(void);
|
||||
void vector156(void);
|
||||
void vector157(void);
|
||||
void vector158(void);
|
||||
void vector159(void);
|
||||
void vector160(void);
|
||||
void vector161(void);
|
||||
void vector162(void);
|
||||
void vector163(void);
|
||||
void vector164(void);
|
||||
void vector165(void);
|
||||
void vector166(void);
|
||||
void vector167(void);
|
||||
void vector168(void);
|
||||
void vector169(void);
|
||||
void vector170(void);
|
||||
void vector171(void);
|
||||
void vector172(void);
|
||||
void vector173(void);
|
||||
void vector174(void);
|
||||
void vector175(void);
|
||||
void vector176(void);
|
||||
void vector177(void);
|
||||
void vector178(void);
|
||||
void vector179(void);
|
||||
void vector180(void);
|
||||
void vector181(void);
|
||||
void vector182(void);
|
||||
void vector183(void);
|
||||
void vector184(void);
|
||||
void vector185(void);
|
||||
void vector186(void);
|
||||
void vector187(void);
|
||||
void vector188(void);
|
||||
void vector189(void);
|
||||
void vector190(void);
|
||||
void vector191(void);
|
||||
void vector192(void);
|
||||
void vector193(void);
|
||||
void vector194(void);
|
||||
void vector195(void);
|
||||
void vector196(void);
|
||||
void vector197(void);
|
||||
void vector198(void);
|
||||
void vector199(void);
|
||||
void vector200(void);
|
||||
void vector201(void);
|
||||
void vector202(void);
|
||||
void vector203(void);
|
||||
void vector204(void);
|
||||
void vector205(void);
|
||||
void vector206(void);
|
||||
void vector207(void);
|
||||
void vector208(void);
|
||||
void vector209(void);
|
||||
void vector210(void);
|
||||
void vector211(void);
|
||||
void vector212(void);
|
||||
void vector213(void);
|
||||
void vector214(void);
|
||||
void vector215(void);
|
||||
void vector216(void);
|
||||
void vector217(void);
|
||||
void vector218(void);
|
||||
void vector219(void);
|
||||
void vector220(void);
|
||||
void vector221(void);
|
||||
void vector222(void);
|
||||
void vector223(void);
|
||||
void vector224(void);
|
||||
void vector225(void);
|
||||
void vector226(void);
|
||||
void vector227(void);
|
||||
void vector228(void);
|
||||
void vector229(void);
|
||||
void vector230(void);
|
||||
void vector231(void);
|
||||
void vector232(void);
|
||||
void vector233(void);
|
||||
void vector234(void);
|
||||
void vector235(void);
|
||||
void vector236(void);
|
||||
void vector237(void);
|
||||
void vector238(void);
|
||||
void vector239(void);
|
||||
void vector240(void);
|
||||
void vector241(void);
|
||||
void vector242(void);
|
||||
void vector243(void);
|
||||
void vector244(void);
|
||||
void vector245(void);
|
||||
void vector246(void);
|
||||
void vector247(void);
|
||||
void vector248(void);
|
||||
void vector249(void);
|
||||
void vector250(void);
|
||||
void vector251(void);
|
||||
void vector252(void);
|
||||
void vector253(void);
|
||||
void vector254(void);
|
||||
void vector255(void);
|
||||
|
||||
#endif
|
||||
100
portable/GCC/XEN_x86/x86-64/x86_64.h
Normal file
100
portable/GCC/XEN_x86/x86-64/x86_64.h
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/* x86_64
|
||||
*
|
||||
* Copyright (C) 2025 Advanced Micro Devices, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _X86_64_H_
|
||||
#define _X86_64_H_
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include <memory.h>
|
||||
|
||||
#if defined(__x86_64__)
|
||||
// Max number of heap regions
|
||||
#define MAX_HEAP_REGIONS 64
|
||||
|
||||
// Multiboot tages that we are interested in
|
||||
#define MULTIBOOT_TAG_TYPE_MODULE 3
|
||||
#define MULTIBOOT_TAG_TYPE_MEMORY 6
|
||||
#define MULTIBOOT_TAG_TYPE_END 0
|
||||
|
||||
// Regions - Read Only or Read-Write
|
||||
#define REGION_RO 0
|
||||
#define REGION_RW 1
|
||||
|
||||
struct multiboot_tag {
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
};
|
||||
struct multiboot_tag_mmap {
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
uint32_t entry_size;
|
||||
uint32_t entry_version;
|
||||
struct multiboot_mmap_entry {
|
||||
uint64_t base_addr;
|
||||
uint64_t length;
|
||||
uint32_t type;
|
||||
uint32_t reserved;
|
||||
} entries[];
|
||||
};
|
||||
|
||||
struct multiboot_info {
|
||||
uint32_t total_size;
|
||||
uint32_t reserved;
|
||||
struct multiboot_tag tags[];
|
||||
};
|
||||
|
||||
#define PAGE_SIZE_1GB (1ULL << 30)
|
||||
#define PAGE_SIZE_4K (1ULL << 12)
|
||||
#define PGD_INDEX(addr) (((addr) >> 39) & 0x1FF)
|
||||
#define PUD_INDEX(addr) (((addr) >> 30) & 0x1FF)
|
||||
#define PMD_INDEX(addr) (((addr) >> 21) & 0x1FF)
|
||||
#define PT_INDEX(addr) (((addr) >> 12) & 0x1FF)
|
||||
|
||||
#define USER_VA_START 0xFFFF800000000000ULL
|
||||
|
||||
#define PAGE_TABLE_SIZE 512
|
||||
|
||||
|
||||
// Extern variable defined in linker script and assembly code
|
||||
extern uint64_t pml4;
|
||||
extern uint64_t pud;
|
||||
extern uint8_t end;
|
||||
|
||||
|
||||
/* Setup Identity Mapping for Kernel */
|
||||
void vSetupKernelPageMapping(void);
|
||||
|
||||
/* Parse user modules loaded as part of boot. Return
|
||||
* end address of user modules
|
||||
*/
|
||||
void vInitMemoryAllocator(uint64_t);
|
||||
void vx86_64Init(uint64_t multiboot_info_addr);
|
||||
uint32_t xInitiRegionForRestrictedTask(MemoryRegion_t *regions);
|
||||
void vMapPages(uint64_t start_addr,uint64_t end_addr, uint64_t *pgd, uint32_t mode);
|
||||
void vFreeAllPages(uint64_t *pgd);
|
||||
uint64_t *pMallocPageTable(void);
|
||||
#endif
|
||||
#endif
|
||||
191
portable/GCC/XEN_x86/x86-64/x86_64_init.c
Normal file
191
portable/GCC/XEN_x86/x86-64/x86_64_init.c
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
/* x86_64_init
|
||||
*
|
||||
* Copyright (C) 2025 Advanced Micro Devices, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "x86_64.h"
|
||||
#include "task.h"
|
||||
#include "stdio.h"
|
||||
#include "stdio.h"
|
||||
#include "trap.h"
|
||||
#include "xen/memory.h"
|
||||
#include "e820.h"
|
||||
#include "hypervisor.h"
|
||||
#include "xen/hvm/params.h"
|
||||
#include <xen/arch-x86/hvm/start_info.h>
|
||||
|
||||
HeapRegion_t xHeapRegions[MAX_HEAP_REGIONS];
|
||||
|
||||
// DEBUG variables for testing purpose
|
||||
uint64_t pml4_w_user=0;
|
||||
|
||||
// Extern variable defined in linker script and assembly code
|
||||
extern uint64_t pml4;
|
||||
extern uint64_t pud;
|
||||
extern uint8_t end;
|
||||
extern char __system_calls_start;
|
||||
extern char __system_calls_end;
|
||||
extern char __apis_start;
|
||||
extern char __apis_end;
|
||||
extern char __rodata_start;
|
||||
extern char __rodata_end;
|
||||
|
||||
/*
|
||||
* Method to setup regions for restricted tasks.
|
||||
* A restricted task has access to following
|
||||
* user mode
|
||||
* user data
|
||||
* system calls
|
||||
* utilities apis like strlen
|
||||
* its process stack
|
||||
*/
|
||||
uint32_t xInitiRegionForRestrictedTask(MemoryRegion_t *regions) ;
|
||||
void vInitMemoryAllocator(uint64_t multiboot_info_addr);
|
||||
void vx86_64Init(uint64_t multiboot_info_addr) ;
|
||||
void vSetupKernelPageMapping(void) ;
|
||||
uint32_t xInitiRegionForRestrictedTask(MemoryRegion_t *regions) {
|
||||
|
||||
uint32_t num_region_used = 0;
|
||||
regions[num_region_used].pvBaseAddress = &__system_calls_start;
|
||||
regions[num_region_used].ulLengthInBytes = (uint32_t) (&__system_calls_end - &__system_calls_start);
|
||||
regions[num_region_used].ulParameters = REGION_RO;
|
||||
num_region_used++;
|
||||
|
||||
regions[num_region_used].pvBaseAddress = &__apis_start;
|
||||
regions[num_region_used].ulLengthInBytes = (uint32_t) (&__apis_end - &__apis_start);
|
||||
regions[num_region_used].ulParameters = REGION_RO;
|
||||
num_region_used++;
|
||||
|
||||
regions[num_region_used].pvBaseAddress = &__rodata_start;
|
||||
regions[num_region_used].ulLengthInBytes = (uint32_t) (&__rodata_end - &__rodata_start);
|
||||
regions[num_region_used].ulParameters = REGION_RO;
|
||||
num_region_used++;
|
||||
|
||||
return num_region_used;
|
||||
}
|
||||
|
||||
#define PAGE_SIZE_1GB (1ULL << 30)
|
||||
#define PML4_INDEX(va) (((va) >> 39) & 0x1FF)
|
||||
#define PDPT_INDEX(va) (((va) >> 30) & 0x1FF)
|
||||
|
||||
/* Setup Mapping for Kernel */
|
||||
void vSetupKernelPageMapping() {
|
||||
uint64_t *page_table_l4_addr = &pml4;
|
||||
uint64_t *page_table_l3_addr = &pud;
|
||||
uint64_t addr = 0;
|
||||
for (int i=0;i<256;i++) {
|
||||
page_table_l4_addr[i] = (uint64_t) &page_table_l3_addr[i*512];
|
||||
page_table_l4_addr[i] |= 0x03;
|
||||
for (int j=0;j<512;j++) {
|
||||
page_table_l3_addr[i*(int)512+j]=addr|(uint64_t)0x83;
|
||||
addr += 0x40000000ULL;
|
||||
}
|
||||
}
|
||||
addr = 0;
|
||||
for (int i=256;i<512;i++) {
|
||||
page_table_l4_addr[i] = (uint64_t) &page_table_l3_addr[i*512];
|
||||
page_table_l4_addr[i] |= 0x03;
|
||||
for (int j=0;j<512;j++) {
|
||||
page_table_l3_addr[i*(int)512+j]=addr|(uint64_t)0x83;
|
||||
addr += 0x40000000ULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void vInitMemoryAllocator(uint64_t multiboot_info_addr)
|
||||
{
|
||||
// Find the end address where kernel is loaded.
|
||||
// Free Memory can started only from that address
|
||||
uint64_t last_used_addr = (uint64_t) &end;
|
||||
int heap_region_count = 0;
|
||||
printf("kernel end: %p\n",last_used_addr);
|
||||
if (multiboot_info_addr != (uint64_t)0) {
|
||||
uint64_t* val = (uint64_t*) multiboot_info_addr;
|
||||
uint32_t magic = *((uint64_t *)val);
|
||||
|
||||
if (magic != XEN_HVM_START_MAGIC_VALUE) {
|
||||
struct multiboot_tag *tag = (struct multiboot_tag *)(multiboot_info_addr + (uint64_t)8); // Skip total size and reserved field
|
||||
|
||||
while (tag->type != (uint32_t)0) { // 0 indicates end tag
|
||||
if (tag->type == (uint32_t)MULTIBOOT_TAG_TYPE_MEMORY) {
|
||||
struct multiboot_tag_mmap *mmap_tag = (struct multiboot_tag_mmap *)tag;
|
||||
for (uint32_t i = 0; i < (mmap_tag->size - 16) / mmap_tag->entry_size; i++) {
|
||||
struct multiboot_mmap_entry *entry = &mmap_tag->entries[i];
|
||||
if (entry->type == 1) {
|
||||
uint64_t start_addr = entry->base_addr;
|
||||
uint64_t end_addr = start_addr + entry->length;
|
||||
if (start_addr > last_used_addr) {
|
||||
xHeapRegions[heap_region_count].pucStartAddress = (uint8_t *) start_addr;
|
||||
xHeapRegions[heap_region_count].xSizeInBytes = entry->length;
|
||||
heap_region_count++;
|
||||
} else if (end_addr > last_used_addr) {
|
||||
xHeapRegions[heap_region_count].pucStartAddress = (uint8_t *)last_used_addr;
|
||||
xHeapRegions[heap_region_count].xSizeInBytes = end_addr - last_used_addr;
|
||||
heap_region_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tag = (struct multiboot_tag *)((uint8_t *)tag + ((tag->size + 7) & ~7)); // Align tag size to 8
|
||||
}
|
||||
} else {
|
||||
struct hvm_start_info *hsi = (struct hvm_start_info *)val;
|
||||
long ret;
|
||||
struct xen_memory_map memmap;
|
||||
memmap.nr_entries = E820_MAX;
|
||||
set_xen_guest_handle(memmap.buffer, e820_map);
|
||||
ret = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap);
|
||||
unsigned long end, start;
|
||||
struct e820entry *entry = (struct e820entry *)e820_map;
|
||||
for ( int i = 0; i < memmap.nr_entries; i++ )
|
||||
{
|
||||
if (entry[i].type == XEN_HVM_MEMMAP_TYPE_RAM) {
|
||||
uint64_t start_addr = entry[i].addr;
|
||||
uint64_t end_addr = entry[i].addr+entry[i].size;
|
||||
if (start_addr > last_used_addr) {
|
||||
xHeapRegions[heap_region_count].pucStartAddress = (uint8_t *) start_addr;
|
||||
xHeapRegions[heap_region_count].xSizeInBytes = entry[i].size;
|
||||
heap_region_count++;
|
||||
} else if (end_addr > last_used_addr) {
|
||||
xHeapRegions[heap_region_count].pucStartAddress = (uint8_t *)last_used_addr;
|
||||
xHeapRegions[heap_region_count].xSizeInBytes = end_addr - last_used_addr;
|
||||
heap_region_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
xHeapRegions[heap_region_count].pucStartAddress = 0;
|
||||
xHeapRegions[heap_region_count].xSizeInBytes = 0;
|
||||
vPortDefineHeapRegions( xHeapRegions );
|
||||
return;
|
||||
}
|
||||
|
||||
void vx86_64Init(uint64_t multiboot_info_addr) {
|
||||
vIDTInit();
|
||||
vSetupKernelPageMapping();
|
||||
vInitMemoryAllocator(multiboot_info_addr);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue