]>
wirehaze git hosting - ppos.git/blob - ppos/kernel/ctx.h
1 // PingPongOS - PingPong Operating System
2 // Prof. Carlos A. Maziero, DINF UFPR
3 // Versão 2.0 -- Junho de 2025
5 // ATENÇÃO: ESTE ARQUIVO NÃO DEVE SER ALTERADO;
6 // ALTERAÇÕES SERÃO DESCARTADAS NA CORREÇÃO.
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/
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.
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).
26 // verificação de processador
28 #error "This library is designed specifically for x86_64 processors."
31 // verificação de sistema operacional
33 #error "This library is designed specifically for Linux OS."
36 // verificação de compilador (flags de otimização -O)
38 #error "Optimizations (-O*) may interfere with the context switching"
41 //----------------------------------------------------------------------
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.
56 // instruction pointer
59 // stack pointer & base
62 // registradores gerais
63 uint64_t rdi
, rsi
, rax
, rbx
, rcx
, rdx
;
64 uint64_t r8
, r9
, r10
, r11
, r12
, r13
, r14
, r15
;
66 // endereço e tamanho da pilha associada a este contexto
69 } __attribute__((aligned(16)));
71 //----------------------------------------------------------------------
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).
82 int ctx_create(struct ctx_t
*ctx
, void(entry
)(void *),
83 void *arg
, void *stack
, uint64_t size
);
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).
90 int ctx_swap(struct ctx_t
*ctx1
, struct ctx_t
*ctx2
);