The Pedigree Project 0.1
x64/state.h
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#ifndef KERNEL_PROCESSOR_X64_STATE_H
21#define KERNEL_PROCESSOR_X64_STATE_H
22#include <config.h>
23
24// IWYU pragma: private, include "pedigree/kernel/processor/state.h"
25
26#include "pedigree/kernel/Log.h"
27#include "pedigree/kernel/compiler.h"
28#include "pedigree/kernel/processor/types.h"
29
34 uint16_t ds, es, fs, gs;
35 uint64_t fsBase, gsBase, origRax;
36} PACKED;
37
38static_assert(sizeof(X64UserEntryMetadata) == 32, "x64 entry metadata layout");
39
40#if X64 && !HOSTED
41extern "C" EXPORTED_PUBLIC void pedigree_materialize_user_entry();
42#endif
43
45class EXPORTED_PUBLIC X64InterruptState {
46 friend class X64ProcessorState;
47 friend class X64InterruptManager;
48 friend class PageFaultHandler;
49
50 public:
51 const X64UserEntryMetadata& getUserEntryMetadata() const {
52 return m_UserEntry;
53 }
54 void setUserEntryMetadata(const X64UserEntryMetadata& metadata) {
55#if X64 && !HOSTED
56 pedigree_materialize_user_entry();
57#endif
58 m_UserEntry = metadata;
59 }
60 void refreshUserTlsBase();
61
62 //
63 // General Interface (InterruptState, SyscallState & ProcessorState)
64 //
67 inline uintptr_t getStackPointer() const;
70 inline void setStackPointer(uintptr_t stackPointer);
74 inline uintptr_t getInstructionPointer() const;
77 inline void setInstructionPointer(uintptr_t instructionPointer);
80 inline uintptr_t getBasePointer() const;
83 inline void setBasePointer(uintptr_t basePointer);
84
85 //
86 // General Interface (InterruptState & SyscallState)
87 //
90 size_t getRegisterCount() const;
94 processor_register_t getRegister(size_t index) const;
98 void setRegister(size_t index, uintptr_t value);
102 const char* getRegisterName(size_t index) const;
106 inline size_t getRegisterSize(size_t index) const;
107
108 //
109 // InterruptState Interface
110 //
113 inline bool kernelMode() const;
116 inline size_t getInterruptNumber() const;
118 inline uintptr_t getErrorCode() const;
120 inline uint16_t getCodeSegment() const;
122 inline uint16_t getStackSegment() const;
123
126 inline uint64_t getFlags() const;
129 inline void setFlags(uint64_t flags);
130
133 static X64InterruptState* construct(class X64ProcessorState& state, bool userMode,
134 const X64UserEntryMetadata& metadata);
135
136 private:
149
150 X64UserEntryMetadata m_UserEntry;
151
153 uint64_t m_R15;
155 uint64_t m_R14;
157 uint64_t m_R13;
159 uint64_t m_R12;
161 uint64_t m_R11;
163 uint64_t m_R10;
165 uint64_t m_R9;
167 uint64_t m_R8;
169 uint64_t m_Rbp;
171 uint64_t m_Rsi;
173 uint64_t m_Rdi;
175 uint64_t m_Rdx;
177 uint64_t m_Rcx;
179 uint64_t m_Rbx;
181 uint64_t m_Rax;
183 uint64_t m_IntNumber;
185 uint64_t m_Errorcode;
187 uint64_t m_Rip;
189 uint64_t m_Cs;
191 uint64_t m_Rflags;
193 uint64_t m_Rsp;
195 uint64_t m_Ss;
196} PACKED;
197
200 friend class X64ProcessorState;
201 friend class X64SyscallManager;
202
203 public:
204 const X64UserEntryMetadata& getUserEntryMetadata() const {
205#if X64 && !HOSTED
206 pedigree_materialize_user_entry();
207#endif
208 return m_UserEntry;
209 }
210 void setUserEntryMetadata(const X64UserEntryMetadata& metadata) {
211#if X64 && !HOSTED
212 pedigree_materialize_user_entry();
213#endif
214 m_UserEntry = metadata;
215 }
216 void refreshUserTlsBase();
217
218 //
219 // General Interface (InterruptState, SyscallState & ProcessorState)
220 //
223 inline uintptr_t getStackPointer() const;
226 inline void setStackPointer(uintptr_t stackPointer);
230 inline uintptr_t getInstructionPointer() const;
233 inline void setInstructionPointer(uintptr_t instructionPointer);
236 inline uintptr_t getBasePointer() const;
239 inline void setBasePointer(uintptr_t basePointer);
240
241 //
242 // General Interface (InterruptState & SyscallState)
243 //
246 size_t getRegisterCount() const;
250 EXPORTED_PUBLIC processor_register_t getRegister(size_t index) const;
252 EXPORTED_PUBLIC void setRegister(size_t index, uintptr_t value);
256 const char* getRegisterName(size_t index) const;
260 inline size_t getRegisterSize(size_t index) const;
261
262 //
263 // SyscallState Interface
264 //
267 inline size_t getSyscallService() const;
270 inline size_t getSyscallNumber() const;
272 ALWAYS_INLINE inline uintptr_t getSyscallParameter(size_t n) const;
273 inline void setSyscallReturnValue(uintptr_t val);
274 inline void setSyscallErrno(uintptr_t val);
275
276 inline uint64_t getFlags() const;
277 inline void setFlags(uint64_t newFlags);
278
279 public:
280 X64UserEntryMetadata m_UserEntry;
281
283 uint64_t m_R15;
285 uint64_t m_R14;
287 uint64_t m_R13;
289 uint64_t m_R12;
291 uint64_t m_R10;
293 uint64_t m_R9;
295 uint64_t m_R8;
297 uint64_t m_Rbp;
298
299 public:
301 uint64_t m_Rsi;
303 uint64_t m_Rdi;
304
305 private:
307 uint64_t m_Rdx;
309 uint64_t m_Rbx;
311 uint64_t m_Rax;
313 uint64_t m_RFlagsR11;
315 uint64_t m_RipRcx;
317 uint64_t m_Rsp;
318} PACKED;
319
322 public:
324 inline X64ProcessorState();
332 inline X64ProcessorState(const X64SyscallState&);
342 inline ~X64ProcessorState();
343
344 //
345 // General Interface (InterruptState, SyscallState & ProcessorState)
346 //
349 inline uintptr_t getStackPointer() const;
352 inline void setStackPointer(uintptr_t stackPointer);
356 inline uintptr_t getInstructionPointer() const;
359 inline void setInstructionPointer(uintptr_t instructionPointer);
362 inline uintptr_t getBasePointer() const;
365 inline void setBasePointer(uintptr_t basePointer);
366
368 uint64_t r15;
370 uint64_t r14;
372 uint64_t r13;
374 uint64_t r12;
376 uint64_t r11;
378 uint64_t r10;
380 uint64_t r9;
382 uint64_t r8;
384 uint64_t rbp;
386 uint64_t rsi;
388 uint64_t rdi;
390 uint64_t rdx;
392 uint64_t rcx;
394 uint64_t rbx;
396 uint64_t rax;
398 uint64_t rip;
400 uint64_t rflags;
402 uint64_t rsp;
403};
404
407 public:
408 uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
409 uint64_t rbx;
410 uint64_t rbp;
411 uint64_t rsp;
412 uint64_t rip;
413
414 uintptr_t getInstructionPointer() const {
415 return rip;
416 }
417
418 // bit 0: Has FPU
419 // bit 1: Used SSE
420 uint32_t flags;
421
422 uint8_t x87FPU_MMX_XMM_MXCSR_State[512 + 16] __attribute__((aligned(16)));
423};
424
427//
428// Part of the Implementation
429//
431 return m_Rsp;
432}
433void X64InterruptState::setStackPointer(uintptr_t stackPointer) {
434 m_Rsp = stackPointer;
435}
437 return m_Rip;
438}
439void X64InterruptState::setInstructionPointer(uintptr_t instructionPointer) {
440 m_Rip = instructionPointer;
441}
443 return m_Rbp;
444}
445void X64InterruptState::setBasePointer(uintptr_t basePointer) {
446 m_Rbp = basePointer;
447}
448size_t X64InterruptState::getRegisterSize(size_t index) const {
449 return 8;
450}
451
453 return (m_Cs == 0x08);
454}
456 return m_IntNumber;
457}
459 return m_Errorcode;
460}
462 return static_cast<uint16_t>(m_Cs);
463}
465 return static_cast<uint16_t>(m_Ss);
466}
467
469 return m_Rflags;
470}
471void X64InterruptState::setFlags(uint64_t flags) {
472 m_Rflags = flags;
473}
474
476 return m_Rsp;
477}
478void X64SyscallState::setStackPointer(uintptr_t stackPointer) {
479 m_Rsp = stackPointer;
480}
482 return m_RipRcx;
483}
484void X64SyscallState::setInstructionPointer(uintptr_t instructionPointer) {
485 m_RipRcx = instructionPointer;
486}
488 return m_Rbp;
489}
490void X64SyscallState::setBasePointer(uintptr_t basePointer) {
491 m_Rbp = basePointer;
492}
493size_t X64SyscallState::getRegisterSize(size_t index) const {
494 return 8;
495}
496
498 return ((m_Rax >> 16) & 0xFFFF);
499}
501 return (m_Rax & 0xFFFF);
502}
503uintptr_t X64SyscallState::getSyscallParameter(size_t n) const {
504 switch (n) {
505 case 0:
506 return m_Rbx;
507 case 1:
508 return m_Rdx;
509 case 2:
510 return m_Rsi;
511 case 3:
512 return m_Rdi;
513 case 4:
514 return m_R8;
515 case 5:
516 return m_R9;
517
518 // redirection for linux syscall parameters
519 case 6:
520 return m_Rdi;
521 case 7:
522 return m_Rsi;
523 case 8:
524 return m_Rdx;
525 case 9:
526 return m_R10;
527 case 10:
528 return m_R8;
529 case 11:
530 return m_R9;
531
532 default:
533 WARNING("Bad syscall parameter requested: " << Dec << n);
534 return 0;
535 }
536}
537void X64SyscallState::setSyscallReturnValue(uintptr_t val) {
538 m_Rax = val;
539}
540void X64SyscallState::setSyscallErrno(uintptr_t val) {
541 m_Rbx = val;
542}
543uint64_t X64SyscallState::getFlags() const {
544 return m_RFlagsR11;
545}
546void X64SyscallState::setFlags(uint64_t newFlags) {
547 m_RFlagsR11 = newFlags;
548}
549
551 : r15(),
552 r14(),
553 r13(),
554 r12(),
555 r11(),
556 r10(),
557 r9(),
558 r8(),
559 rbp(),
560 rsi(),
561 rdi(),
562 rdx(),
563 rcx(),
564 rbx(),
565 rax(),
566 rip(),
567 rflags(),
568 rsp() {}
570 : r15(x.r15),
571 r14(x.r14),
572 r13(x.r13),
573 r12(x.r12),
574 r11(x.r11),
575 r10(x.r10),
576 r9(x.r9),
577 r8(x.r8),
578 rbp(x.rbp),
579 rsi(x.rsi),
580 rdi(x.rdi),
581 rdx(x.rdx),
582 rcx(x.rcx),
583 rbx(x.rbx),
584 rax(x.rax),
585 rip(x.rip),
586 rflags(x.rflags),
587 rsp(x.rsp) {}
589 : r15(x.m_R15),
590 r14(x.m_R14),
591 r13(x.m_R13),
592 r12(x.m_R12),
593 r11(x.m_R11),
594 r10(x.m_R10),
595 r9(x.m_R9),
596 r8(x.m_R8),
597 rbp(x.m_Rbp),
598 rsi(x.m_Rsi),
599 rdi(x.m_Rdi),
600 rdx(x.m_Rdx),
601 rcx(x.m_Rcx),
602 rbx(x.m_Rbx),
603 rax(x.m_Rax),
604 rip(x.m_Rip),
605 rflags(x.m_Rflags),
606 rsp(x.m_Rsp) {}
608 : r15(x.m_R15),
609 r14(x.m_R14),
610 r13(x.m_R13),
611 r12(x.m_R12),
612 r11(x.m_RFlagsR11),
613 r10(x.m_R10),
614 r9(x.m_R9),
615 r8(x.m_R8),
616 rbp(x.m_Rbp),
617 rsi(x.m_Rsi),
618 rdi(x.m_Rdi),
619 rdx(x.m_Rdx),
620 rcx(x.m_RipRcx),
621 rbx(x.m_Rbx),
622 rax(x.m_Rax),
623 rip(x.m_RipRcx),
624 rflags(x.m_RFlagsR11),
625 rsp(x.m_Rsp) {}
627 r15 = x.r15;
628 r14 = x.r14;
629 r13 = x.r13;
630 r12 = x.r12;
631 r11 = x.r11;
632 r10 = x.r10;
633 r9 = x.r9;
634 r8 = x.r8;
635 rbp = x.rbp;
636 rsi = x.rsi;
637 rdi = x.rdi;
638 rdx = x.rdx;
639 rcx = x.rcx;
640 rbx = x.rbx;
641 rax = x.rax;
642 rip = x.rip;
643 rflags = x.rflags;
644 rsp = x.rsp;
645 return *this;
646}
648 r15 = x.m_R15;
649 r14 = x.m_R14;
650 r13 = x.m_R13;
651 r12 = x.m_R12;
652 r11 = x.m_R11;
653 r10 = x.m_R10;
654 r9 = x.m_R9;
655 r8 = x.m_R8;
656 rbp = x.m_Rbp;
657 rsi = x.m_Rsi;
658 rdi = x.m_Rdi;
659 rdx = x.m_Rdx;
660 rcx = x.m_Rcx;
661 rbx = x.m_Rbx;
662 rax = x.m_Rax;
663 rip = x.m_Rip;
664 rflags = x.m_Rflags;
665 rsp = x.m_Rsp;
666 return *this;
667}
669 r15 = x.m_R15;
670 r14 = x.m_R14;
671 r13 = x.m_R13;
672 r12 = x.m_R12;
673 r11 = x.m_RFlagsR11;
674 r10 = x.m_R10;
675 r9 = x.m_R9;
676 r8 = x.m_R8;
677 rbp = x.m_Rbp;
678 rsi = x.m_Rsi;
679 rdi = x.m_Rdi;
680 rdx = x.m_Rdx;
681 rcx = x.m_RipRcx;
682 rbx = x.m_Rbx;
683 rax = x.m_Rax;
684 rip = x.m_RipRcx;
685 rflags = x.m_RFlagsR11;
686 rsp = x.m_Rsp;
687 return *this;
688}
690
692 return rsp;
693}
694void X64ProcessorState::setStackPointer(uintptr_t stackPointer) {
695 rsp = stackPointer;
696}
698 return rip;
699}
700void X64ProcessorState::setInstructionPointer(uintptr_t instructionPointer) {
701 rip = instructionPointer;
702}
704 return rbp;
705}
706void X64ProcessorState::setBasePointer(uintptr_t basePointer) {
707 rbp = basePointer;
708}
709
710#endif
X64InterruptState(const X64InterruptState &)
uintptr_t getStackPointer() const
Definition x64/state.h:430
uintptr_t getInstructionPointer() const
Definition x64/state.h:436
bool kernelMode() const
Definition x64/state.h:452
void setInstructionPointer(uintptr_t instructionPointer)
Definition x64/state.h:439
uint64_t getFlags() const
Definition x64/state.h:468
uintptr_t getErrorCode() const
Definition x64/state.h:458
uint16_t getCodeSegment() const
Definition x64/state.h:461
size_t getInterruptNumber() const
Definition x64/state.h:455
void setBasePointer(uintptr_t basePointer)
Definition x64/state.h:445
uintptr_t getBasePointer() const
Definition x64/state.h:442
uint16_t getStackSegment() const
Definition x64/state.h:464
void setStackPointer(uintptr_t stackPointer)
Definition x64/state.h:433
X64InterruptState & operator=(const X64InterruptState &)
uint64_t m_Errorcode
Definition x64/state.h:185
uint64_t m_Rflags
Definition x64/state.h:191
size_t getRegisterSize(size_t index) const
Definition x64/state.h:448
uint64_t m_IntNumber
Definition x64/state.h:183
void setFlags(uint64_t flags)
Definition x64/state.h:471
X64ProcessorState & operator=(const X64ProcessorState &)
Definition x64/state.h:626
void setBasePointer(uintptr_t basePointer)
Definition x64/state.h:706
uintptr_t getBasePointer() const
Definition x64/state.h:703
void setStackPointer(uintptr_t stackPointer)
Definition x64/state.h:694
uintptr_t getStackPointer() const
Definition x64/state.h:691
void setInstructionPointer(uintptr_t instructionPointer)
Definition x64/state.h:700
uintptr_t getInstructionPointer() const
Definition x64/state.h:697
uint64_t m_Rsi
Definition x64/state.h:301
uintptr_t getBasePointer() const
Definition x64/state.h:487
void setBasePointer(uintptr_t basePointer)
Definition x64/state.h:490
EXPORTED_PUBLIC processor_register_t getRegister(size_t index) const
Definition x64/state.cc:119
uint64_t m_RFlagsR11
Definition x64/state.h:313
uint64_t m_Rdi
Definition x64/state.h:303
uint64_t m_Rax
Definition x64/state.h:311
uint64_t m_R10
Definition x64/state.h:291
const char * getRegisterName(size_t index) const
Definition x64/state.cc:188
void setStackPointer(uintptr_t stackPointer)
Definition x64/state.h:478
uint64_t m_Rsp
Definition x64/state.h:317
uint64_t m_Rdx
Definition x64/state.h:307
size_t getRegisterCount() const
Definition x64/state.cc:116
void setInstructionPointer(uintptr_t instructionPointer)
Definition x64/state.h:484
uintptr_t getInstructionPointer() const
Definition x64/state.h:481
uint64_t m_RipRcx
Definition x64/state.h:315
uint64_t m_R9
Definition x64/state.h:293
ALWAYS_INLINE uintptr_t getSyscallParameter(size_t n) const
Definition x64/state.h:503
uint64_t m_R12
Definition x64/state.h:289
uint64_t m_Rbp
Definition x64/state.h:297
uint64_t m_Rbx
Definition x64/state.h:309
uintptr_t getStackPointer() const
Definition x64/state.h:475
size_t getSyscallNumber() const
Definition x64/state.h:500
uint64_t m_R14
Definition x64/state.h:285
size_t getRegisterSize(size_t index) const
Definition x64/state.h:493
uint64_t m_R13
Definition x64/state.h:287
uint64_t m_R15
Definition x64/state.h:283
size_t getSyscallService() const
Definition x64/state.h:497
uint64_t m_R8
Definition x64/state.h:295
EXPORTED_PUBLIC void setRegister(size_t index, uintptr_t value)
Definition x64/state.cc:154
@ Dec
Definition Log.h:126