]> wirehaze git hosting - ppos.git/blob - ppos/kernel/ctx.h

wirehaze git hosting

tasks implementation (ongoing)
[ppos.git] / ppos / kernel / ctx.h
1 // PingPongOS - PingPong Operating System
2 // Prof. Carlos A. Maziero, DINF UFPR
3 // Versão 2.0 -- Junho de 2025
4
5 // ATENÇÃO: ESTE ARQUIVO NÃO DEVE SER ALTERADO;
6 // ALTERAÇÕES SERÃO DESCARTADAS NA CORREÇÃO.
7
8 /*
9 Rotinas de manipulação de contextos no userspace, inspiradas de
10 https://github.com/kaniini/libucontext/blob/master/arch/x86_64
11 https://graphitemaster.github.io/fibers/
12
13 Estas rotinas são específicas para CPUs x86_64 (Intel/AMD 64 bits)
14 no sistema operacional Linux. Não funcionam em outras plataformas
15 sem as devidas adaptações.
16
17 To-do:
18 - aceitar stack == NULL para não alterar a pilha do contexto.
19 - salvar/restaurar registradores de ponto flutuante %xmm*
20 - SEGV se função do contexto encerrar sem ctx_swap (falta uc_link).
21 */
22
23 #ifndef __CTX__
24 #define __CTX__
25
26 // verificação de processador
27 #ifndef __x86_64__
28 #error "This library is designed specifically for x86_64 processors."
29 #endif
30
31 // verificação de sistema operacional
32 #ifndef __linux__
33 #error "This library is designed specifically for Linux OS."
34 #endif
35
36 // verificação de compilador (flags de otimização -O)
37 #ifdef __OPTIMIZE__
38 #error "Optimizations (-O*) may interfere with the context switching"
39 #endif
40
41 //----------------------------------------------------------------------
42
43 #include <stdint.h>
44
45 #define ERROR -1
46 #define NOERROR 0
47
48 /*
49 Este struct permite salvar um contexto, ou seja, um estado da CPU
50 definido pelos valores de seus principais registradores.
51 Ajuste os offsets dos registradores em ctx.s se alterar algo aqui.
52 Este struct deve ser alocado com alinhamento de 16 bytes.
53 */
54 struct ctx_t
55 {
56 // instruction pointer
57 uint64_t rip;
58
59 // stack pointer & base
60 uint64_t rsp, rbp;
61
62 // registradores gerais
63 uint64_t rdi, rsi, rax, rbx, rcx, rdx;
64 uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
65
66 // endereço e tamanho da pilha associada a este contexto
67 void *stack;
68 unsigned long size;
69 } __attribute__((aligned(16)));
70
71 //----------------------------------------------------------------------
72
73 /*
74 Define um contexto com uma função de entrada e uma pilha própria:
75 - entry: função a ser executada ao ativar este contexto;
76 - arg: argumento para a função "entry" quando ela iniciar;
77 - stack: endereço inicial (mais baixo) da pilha; deve ser
78 previamente alocado e alinhado em 16 bytes;
79 - size: tamanho da pilha, deve ter ao menos 4.096 bytes.
80 Retorno: 0 em sucesso, -1 em erro (vide ctx.s).
81 */
82 int ctx_create(struct ctx_t *ctx, void(entry)(void *),
83 void *arg, void *stack, uint64_t size);
84
85 /*
86 Salva o estado atual da CPU em ctx1 (se não for NULL) e
87 carrega na CPU o estado salvo em ctx2 (se não for NULL).
88 Retorno: 0 em sucesso, -1 em erro (vide ctx.s).
89 */
90 int ctx_swap(struct ctx_t *ctx1, struct ctx_t *ctx2);
91
92 #endif