LibXenon
Bare-metal Xbox 360 homebrew library
Loading...
Searching...
No Matches
vm.c
Go to the documentation of this file.
1#include <ppc/vm.h>
2#include <assert.h>
3#include <stdio.h>
4
5#include "register.h"
6#include "elf/elf_abi.h"
8
9/* Goal is to provide a *simple* memory layout with the following features:
10 - addresses at 0 should pagefault,
11 - memory should be continously mapped (cached),
12 - we need access to PCI space (guarded),
13 - we need access to 0x200_x_x cpu regs (guarded)
14*/
15
16uint32_t pagetable[] __attribute__ ((section (".pagetable"))) = {
17 0, /* zero "page", should pagefault */
18 0,
19 (0x20000000000ULL >> 10) | VM_WIMG_GUARDED, // CPU stuff
20
21 -1, -1, -1, -1, -1, // 1280MB user pages
22
23 (0x00000000 >> 10) | VM_WIMG_CACHED,
24 (0x10000000 >> 10) | VM_WIMG_CACHED,
25
26 (0x00000000 >> 10) | VM_WIMG_GUARDED,
27 (0x10000000 >> 10) | VM_WIMG_GUARDED,
28
29 (0xc0000000 >> 10) | VM_WIMG_GUARDED, // Flash (at 0xc8000000)
30 (0xd0000000 >> 10) | VM_WIMG_GUARDED, // PCI config space
31 (0xe0000000 >> 10) | VM_WIMG_GUARDED, // PCI space
32 0,
33};
34
37
38static void vm_invalidate_tlb(uint32_t ea)
39{
40 asm volatile ("tlbiel %0,1"::"r"(ea));
41 asm volatile ("ptesync");
42 asm volatile ("eieio");
43}
44
45static int vm_common_check_get_idx(uint32_t virt_addr, int size)
46{
47 assert(!(virt_addr&VM_USER_PAGE_MASK));
48 assert(!(size&VM_USER_PAGE_MASK));
49 assert(virt_addr>=0x30000000 && virt_addr<0x80000000);
50
51 return (virt_addr-0x30000000)>>VM_USER_PAGE_BITS;
52}
53
54void vm_create_user_mapping(uint32_t virt_addr, uint64_t phys_addr, int size, int wimg)
55{
56 assert(!(phys_addr&VM_USER_PAGE_MASK));
57
58 int page_idx=vm_common_check_get_idx(virt_addr,size);
59 int page_addr=phys_addr | wimg;
60
61 while (size)
62 {
63 userpagetable[page_idx]=page_addr;
64
65 vm_invalidate_tlb(virt_addr);
66
68 ++page_idx;
69 page_addr+=VM_USER_PAGE_SIZE;
70 virt_addr+=VM_USER_PAGE_SIZE;
71 }
72}
73
75{
76 int page_idx=vm_common_check_get_idx(virt_addr,size);
77
78 while (size)
79 {
80 userpagetable[page_idx]=0;
81
82 vm_invalidate_tlb(virt_addr);
83
85 ++page_idx;
86 virt_addr+=VM_USER_PAGE_SIZE;
87 }
88}
89
90void vm_set_user_mapping_flags(uint32_t virt_addr, int size, int wimg)
91{
92 int page_idx=vm_common_check_get_idx(virt_addr,size);
93
94 while (size)
95 {
96 if(userpagetable[page_idx])
97 {
98 userpagetable[page_idx]&=~VM_USER_PAGE_MASK;
99 userpagetable[page_idx]|=wimg;
100
101 vm_invalidate_tlb(virt_addr);
102 }
103
105 ++page_idx;
106 virt_addr+=VM_USER_PAGE_SIZE;
107 }
108}
109
111{
112 vm_segfault_handler=handler;
113}
#define NULL
Definition: def.h:47
u32 size
Definition: iso9660.c:537
u32 uint32_t
Definition: libfdt_env.h:11
u64 uint64_t
Definition: libfdt_env.h:12
unsigned int __mf_uintptr_t __attribute__((__mode__(__pointer__)))
Definition: mf-runtime.h:34
void vm_set_user_mapping_flags(uint32_t virt_addr, int size, int wimg)
Definition: vm.c:90
void vm_set_user_mapping_segfault_handler(vm_segfault_handler_t handler)
Definition: vm.c:110
void vm_destroy_user_mapping(uint32_t virt_addr, int size)
Definition: vm.c:74
uint32_t userpagetable[1280 *1024 *1024/VM_USER_PAGE_SIZE]
Definition: vm.c:35
void vm_create_user_mapping(uint32_t virt_addr, uint64_t phys_addr, int size, int wimg)
Definition: vm.c:54
vm_segfault_handler_t vm_segfault_handler
Definition: vm.c:36
#define VM_USER_PAGE_BITS
Definition: vm.h:8
#define VM_USER_PAGE_SIZE
Definition: vm.h:9
#define VM_WIMG_CACHED
Definition: vm.h:12
#define VM_WIMG_GUARDED
Definition: vm.h:13
#define VM_USER_PAGE_MASK
Definition: vm.h:10
void *(* vm_segfault_handler_t)(int, void *, void *, int)
Definition: vm.h:18