Changeset e12ccc5 in mainline
- Timestamp:
- 2006-08-01T17:27:11Z (18 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0fbfa0d
- Parents:
- e386cbf
- Location:
- kernel/arch/xen32
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/xen32/include/boot/boot.h
re386cbf re12ccc5 37 37 38 38 #define GUEST_CMDLINE 1024 39 #define VIRT_CPUS 32 39 40 #define START_INFO_SIZE 1104 41 40 42 #define BOOT_OFFSET 0x0000 43 #define XEN_VIRT_START 0xFC000000 44 45 #define TEMP_STACK_SIZE 0x1000 41 46 42 47 #ifndef __ASM__ 43 48 49 #define mp_map ((pfn_t *) XEN_VIRT_START) 50 44 51 #include <arch/types.h> 52 53 typedef uint32_t evtchn_t; 54 55 typedef struct { 56 uint32_t version; 57 uint32_t pad0; 58 uint64_t tsc_timestamp; /**< TSC at last update of time vals */ 59 uint64_t system_time; /**< Time, in nanosecs, since boot */ 60 uint32_t tsc_to_system_mul; 61 int8_t tsc_shift; 62 int8_t pad1[3]; 63 } vcpu_time_info_t; 64 65 typedef struct { 66 uint32_t cr2; 67 uint32_t pad[5]; 68 } arch_vcpu_info_t; 69 70 typedef struct arch_shared_info { 71 pfn_t max_pfn; /**< max pfn that appears in table */ 72 uint32_t pfn_to_mfn_frame_list_list; 73 uint32_t nmi_reason; 74 } arch_shared_info_t; 75 76 typedef struct { 77 uint8_t evtchn_upcall_pending; 78 uint8_t evtchn_upcall_mask; 79 evtchn_t evtchn_pending_sel; 80 arch_vcpu_info_t arch; 81 vcpu_time_info_t time; 82 } vcpu_info_t; 83 84 typedef struct { 85 vcpu_info_t vcpu_info[VIRT_CPUS]; 86 evtchn_t evtchn_pending[32]; 87 evtchn_t evtchn_mask[32]; 88 89 uint32_t wc_version; /**< Version counter */ 90 uint32_t wc_sec; /**< Secs 00:00:00 UTC, Jan 1, 1970 */ 91 uint32_t wc_nsec; /**< Nsecs 00:00:00 UTC, Jan 1, 1970 */ 92 93 arch_shared_info_t arch; 94 } shared_info_t; 45 95 46 96 typedef struct { 47 97 int8_t magic[32]; /**< "xen-<version>-<platform>" */ 48 98 uint32_t frames; /**< Available frames */ 49 void *shared_info;/**< Shared info structure (machine address) */99 shared_info_t *shared_info; /**< Shared info structure (machine address) */ 50 100 uint32_t flags; /**< SIF_xxx flags */ 51 101 pfn_t store_mfn; /**< Shared page (machine page) */ 52 uint32_t store_evtchn; /**< Event channel for store communication */102 evtchn_t store_evtchn; /**< Event channel for store communication */ 53 103 void *console_mfn; /**< Console page (machine address) */ 54 uint32_t console_evtchn; /**< Event channel for console messages */104 evtchn_t console_evtchn; /**< Event channel for console messages */ 55 105 pte_t *ptl0; /**< Boot PTL0 (kernel address) */ 56 106 uint32_t pt_frames; /**< Number of bootstrap page table frames */ … … 61 111 } start_info_t; 62 112 113 typedef struct { 114 pfn_t start; 115 pfn_t size; 116 pfn_t reserved; 117 } memzone_t; 118 63 119 extern start_info_t start_info; 120 extern shared_info_t shared_info; 121 extern memzone_t meminfo; 64 122 65 123 #endif -
kernel/arch/xen32/include/hypercall.h
re386cbf re12ccc5 36 36 typedef uint16_t domid_t; 37 37 38 typedef struct { 39 uint64_t ptr; /**< Machine address of PTE */ 40 uint64_t val; /**< New contents of PTE */ 41 } mmu_update_t; 42 43 typedef struct { 44 unsigned int cmd; 45 union { 46 unsigned long mfn; 47 unsigned long linear_addr; 48 } arg1; 49 union { 50 unsigned int nr_ents; 51 void *vcpumask; 52 } arg2; 53 } mmuext_op_t; 54 55 56 #define XEN_MMU_UPDATE 1 57 #define XEN_CONSOLE_IO 18 58 #define XEN_MMUEXT_OP 26 38 39 #define XEN_MMU_UPDATE 1 40 #define XEN_UPDATE_VA_MAPPING 14 41 #define XEN_CONSOLE_IO 18 42 #define XEN_VM_ASSIST 21 43 #define XEN_MMUEXT_OP 26 59 44 60 45 … … 83 68 84 69 70 #define UVMF_NONE 0 /**< No flushing at all */ 71 #define UVMF_TLB_FLUSH 1 /**< Flush entire TLB(s) */ 72 #define UVMF_INVLPG 2 /**< Flush only one entry */ 73 #define UVMF_FLUSHTYPE_MASK 3 74 #define UVMF_MULTI 0 /**< Flush subset of TLBs */ 75 #define UVMF_LOCAL 0 /**< Flush local TLB */ 76 #define UVMF_ALL (1 << 2) /**< Flush all TLBs */ 77 78 79 /* 80 * Commands to XEN_VM_ASSIST 81 */ 82 #define VMASST_CMD_ENABLE 0 83 #define VMASST_CMD_DISABLE 1 84 #define VMASST_TYPE_4GB_SEGMENTS 0 85 #define VMASST_TYPE_4GB_SEGMENTS_NOTIFY 1 86 #define VMASST_TYPE_WRITABLE_PAGETABLES 2 87 88 85 89 #define DOMID_SELF (0x7FF0U) 86 90 #define DOMID_IO (0x7FF1U) … … 190 194 } 191 195 192 static inline int xen_ mmu_update(const mmu_update_t *req, const unsigned int count, unsigned int *success_count, domid_t domid)196 static inline int xen_vm_assist(const unsigned int cmd, const unsigned int type) 193 197 { 194 return hypercall4(XEN_MMU_UPDATE, req, count, success_count, domid);198 return hypercall2(XEN_VM_ASSIST, cmd, type); 195 199 } 196 200 197 static inline int xen_mmuext_op(const mmuext_op_t *op, const unsigned int count, unsigned int *success_count, domid_t domid)198 {199 return hypercall4(XEN_MMUEXT_OP, op, count, success_count, domid);200 }201 202 201 #endif -
kernel/arch/xen32/include/mm/frame.h
re386cbf re12ccc5 47 47 48 48 #define PA2MA(x) ((start_info.pm_map[((uintptr_t) (x)) >> 12] << 12) + (((uintptr_t) (x)) & 0xfff)) 49 50 extern uintptr_t last_frame; 49 #define MA2PA(x) ((mp_map[((uintptr_t) (x)) >> 12] << 12) + (((uintptr_t) (x)) & 0xfff)) 51 50 52 51 extern void frame_arch_init(void); -
kernel/arch/xen32/include/mm/page.h
re386cbf re12ccc5 44 44 45 45 #ifndef __ASM__ 46 # include <arch/hypercall.h>47 46 # define KA2PA(x) (((uintptr_t) (x)) - 0x80000000) 48 47 # define PA2KA(x) (((uintptr_t) (x)) + 0x80000000) … … 66 65 #define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0x3ff) 67 66 68 #define GET_PTL1_ADDRESS_ARCH(ptl0, i) ((pte_t *) ((((pte_t *)(ptl0))[(i)].frame_address) << 12))67 #define GET_PTL1_ADDRESS_ARCH(ptl0, i) ((pte_t *) MA2PA((((pte_t *) (ptl0))[(i)].frame_address) << 12)) 69 68 #define GET_PTL2_ADDRESS_ARCH(ptl1, i) (ptl1) 70 69 #define GET_PTL3_ADDRESS_ARCH(ptl2, i) (ptl2) 71 #define GET_FRAME_ADDRESS_ARCH(ptl3, i) ((uintptr_t) ((((pte_t *)(ptl3))[(i)].frame_address) << 12))70 #define GET_FRAME_ADDRESS_ARCH(ptl3, i) ((uintptr_t) MA2PA((((pte_t *) (ptl3))[(i)].frame_address) << 12)) 72 71 73 72 #define SET_PTL0_ADDRESS_ARCH(ptl0) { \ 74 73 mmuext_op_t mmu_ext; \ 74 \ 75 75 mmu_ext.cmd = MMUEXT_NEW_BASEPTR; \ 76 mmu_ext. arg1.mfn = ADDR2PFN(PA2MA(ptl0)); \76 mmu_ext.mfn = ADDR2PFN(PA2MA(ptl0)); \ 77 77 xen_mmuext_op(&mmu_ext, 1, NULL, DOMID_SELF); \ 78 78 } 79 79 80 #define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) { \ 80 81 mmu_update_t update; \ 82 \ 81 83 update.ptr = PA2MA(KA2PA(&((pte_t *) (ptl0))[(i)])); \ 82 update.val = PA2MA(a) ; \84 update.val = PA2MA(a) | 0x0003; \ 83 85 xen_mmu_update(&update, 1, NULL, DOMID_SELF); \ 84 86 } 85 87 #define SET_PTL2_ADDRESS_ARCH(ptl1, i, a) 86 88 #define SET_PTL3_ADDRESS_ARCH(ptl2, i, a) 87 #define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) { \ 88 mmu_update_t update; \ 89 update.ptr = PA2MA(KA2PA(&((pte_t *) (ptl3))[(i)])); \ 90 update.val = PA2MA(a); \ 91 xen_mmu_update(&update, 1, NULL, DOMID_SELF); \ 92 } 93 94 #define GET_PTL1_FLAGS_ARCH(ptl0, i) get_pt_flags((pte_t *)(ptl0), (index_t)(i)) 89 #define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) (((pte_t *) (ptl3))[(i)].frame_address = PA2MA(a) >> 12) 90 91 #define GET_PTL1_FLAGS_ARCH(ptl0, i) get_pt_flags((pte_t *) (ptl0), (index_t)(i)) 95 92 #define GET_PTL2_FLAGS_ARCH(ptl1, i) PAGE_PRESENT 96 93 #define GET_PTL3_FLAGS_ARCH(ptl2, i) PAGE_PRESENT 97 #define GET_FRAME_FLAGS_ARCH(ptl3, i) get_pt_flags((pte_t *) (ptl3), (index_t)(i))98 99 #define SET_PTL1_FLAGS_ARCH(ptl0, i, x) set_pt_flags((pte_t *) (ptl0), (index_t)(i), (x))94 #define GET_FRAME_FLAGS_ARCH(ptl3, i) get_pt_flags((pte_t *) (ptl3), (index_t)(i)) 95 96 #define SET_PTL1_FLAGS_ARCH(ptl0, i, x) set_pt_flags((pte_t *) (ptl0), (index_t)(i), (x)) 100 97 #define SET_PTL2_FLAGS_ARCH(ptl1, i, x) 101 98 #define SET_PTL3_FLAGS_ARCH(ptl2, i, x) 102 #define SET_FRAME_FLAGS_ARCH(ptl3, i, x) set_pt_flags((pte_t *)(ptl3), (index_t)(i), (x))99 #define SET_FRAME_FLAGS_ARCH(ptl3, i, x) set_pt_flags((pte_t *) (ptl3), (index_t)(i), (x)) 103 100 104 101 #define PTE_VALID_ARCH(p) (*((uint32_t *) (p)) != 0) … … 114 111 #include <arch/mm/frame.h> 115 112 #include <typedefs.h> 113 #include <arch/hypercall.h> 116 114 117 115 /* Page fault error codes. */ … … 145 143 } __attribute__ ((packed)); 146 144 145 typedef struct { 146 uint64_t ptr; /**< Machine address of PTE */ 147 union { /**< New contents of PTE */ 148 uint64_t val; 149 pte_t pte; 150 }; 151 } mmu_update_t; 152 153 typedef struct { 154 unsigned int cmd; 155 union { 156 unsigned long mfn; 157 unsigned long linear_addr; 158 }; 159 union { 160 unsigned int nr_ents; 161 void *vcpumask; 162 }; 163 } mmuext_op_t; 164 165 static inline int xen_update_va_mapping(const void *va, const pte_t pte, const unsigned int flags) 166 { 167 return hypercall4(XEN_UPDATE_VA_MAPPING, va, pte, 0, flags); 168 } 169 170 static inline int xen_mmu_update(const mmu_update_t *req, const unsigned int count, unsigned int *success_count, domid_t domid) 171 { 172 return hypercall4(XEN_MMU_UPDATE, req, count, success_count, domid); 173 } 174 175 static inline int xen_mmuext_op(const mmuext_op_t *op, const unsigned int count, unsigned int *success_count, domid_t domid) 176 { 177 return hypercall4(XEN_MMUEXT_OP, op, count, success_count, domid); 178 } 179 147 180 static inline int get_pt_flags(pte_t *pt, index_t i) 148 181 { -
kernel/arch/xen32/src/boot/boot.S
re386cbf re12ccc5 33 33 34 34 .section __xen_guest 35 .ascii "GUEST_OS=HelenOS," 36 .ascii "XEN_VER=xen-3.0," 37 .ascii "HYPERCALL_PAGE=0x0000," 38 .ascii "LOADER=generic" 35 .ascii "GUEST_OS=HelenOS," 36 .ascii "XEN_VER=xen-3.0," 37 .ascii "HYPERCALL_PAGE=0x0000," 38 .ascii "LOADER=generic," 39 .ascii "FEATURES=writable_page_tables" 39 40 .byte 0 40 41 … … 52 53 cld 53 54 rep movsb 54 55 56 # switch to temporal kernel stack 57 58 movl $kernel_stack, %esp 59 60 call arch_pre_main 55 61 call main_bsp # never returns 56 62 57 63 cli 58 64 hlt 65 66 kernel_stack_bottom: 67 .space TEMP_STACK_SIZE 68 kernel_stack: 59 69 60 70 .section K_TEXT_START, "aw", @progbits … … 63 73 hypercall_page: 64 74 .space PAGE_SIZE 75 76 .global shared_info 77 .org 0x1000 78 shared_info: 79 .space PAGE_SIZE -
kernel/arch/xen32/src/mm/frame.c
re386cbf re12ccc5 35 35 36 36 #include <mm/frame.h> 37 #include <arch/mm/frame.h>38 #include <mm/as.h>39 37 #include <config.h> 40 #include <arch/boot/boot.h>41 #include <arch/hypercall.h>42 #include <panic.h>43 #include <debug.h>44 #include <align.h>45 #include <macros.h>46 47 #include <console/cmd.h>48 #include <console/kconsole.h>49 50 uintptr_t last_frame = 0;51 52 #define L0_PT_SHIFT 1053 #define L3_PT_SHIFT 054 55 #define L0_PT_ENTRIES 102456 #define L3_PT_ENTRIES 102457 58 #define L0_INDEX_MASK (L0_PT_ENTRIES - 1)59 #define L3_INDEX_MASK (L3_PT_ENTRIES - 1)60 61 #define PFN2PTL0_INDEX(pfn) ((pfn >> L0_PT_SHIFT) & L0_INDEX_MASK)62 #define PFN2PTL3_INDEX(pfn) ((pfn >> L3_PT_SHIFT) & L3_INDEX_MASK)63 64 #define PAGE_MASK (~(PAGE_SIZE - 1))65 66 #define _PAGE_PRESENT 0x001UL67 #define _PAGE_RW 0x002UL68 #define _PAGE_USER 0x004UL69 #define _PAGE_PWT 0x008UL70 #define _PAGE_PCD 0x010UL71 #define _PAGE_ACCESSED 0x020UL72 #define _PAGE_DIRTY 0x040UL73 #define _PAGE_PAT 0x080UL74 #define _PAGE_PSE 0x080UL75 #define _PAGE_GLOBAL 0x100UL76 77 #define L0_PROT (_PAGE_PRESENT | _PAGE_ACCESSED)78 #define L3_PROT (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)79 38 80 39 void frame_arch_init(void) 81 40 { 82 41 if (config.cpu_active == 1) { 83 /* The only memory zone starts just after page table */ 84 pfn_t start = ADDR2PFN(ALIGN_UP(KA2PA(start_info.ptl0), PAGE_SIZE)) + start_info.pt_frames; 85 size_t size = start_info.frames - start; 86 87 /* Create identity mapping */ 88 pfn_t phys; 89 count_t count = 0; 90 for (phys = start; phys < start + size; phys++) { 91 mmu_update_t updates[L3_PT_ENTRIES]; 92 pfn_t virt = ADDR2PFN(PA2KA(PFN2ADDR(phys))); 93 94 size_t ptl0_index = PFN2PTL0_INDEX(virt); 95 size_t ptl3_index = PFN2PTL3_INDEX(virt); 96 97 pte_t *ptl3 = (pte_t *) PFN2ADDR(start_info.ptl0[ptl0_index].frame_address); 98 99 if (ptl3 == 0) { 100 mmuext_op_t mmu_ext; 101 102 pfn_t virt2 = ADDR2PFN(PA2KA(PFN2ADDR(start))); 103 104 /* New L1 page table entry needed */ 105 memsetb(PFN2ADDR(virt2), PAGE_SIZE, 0); 106 107 size_t ptl0_index2 = PFN2PTL0_INDEX(virt2); 108 size_t ptl3_index2 = PFN2PTL3_INDEX(virt2); 109 pte_t *ptl3_2 = (pte_t *) PFN2ADDR(start_info.ptl0[ptl0_index2].frame_address); 110 111 if (ptl3_2 == 0) 112 panic("Unable to find page table reference"); 113 114 updates[count].ptr = (uintptr_t) &ptl3_2[ptl3_index2]; 115 updates[count].val = PA2MA(PFN2ADDR(start)) | L0_PROT; 116 if (xen_mmu_update(updates, count + 1, NULL, DOMID_SELF) < 0) 117 panic("Unable to map new page table"); 118 count = 0; 119 120 mmu_ext.cmd = MMUEXT_PIN_L1_TABLE; 121 mmu_ext.arg1.mfn = ADDR2PFN(PA2MA(PFN2ADDR(start))); 122 if (xen_mmuext_op(&mmu_ext, 1, NULL, DOMID_SELF) < 0) 123 panic("Error pinning new page table"); 124 125 pte_t *ptl0 = (pte_t *) PA2MA(KA2PA(start_info.ptl0)); 126 127 updates[count].ptr = (uintptr_t) &ptl0[ptl0_index]; 128 updates[count].val = PA2MA(PFN2ADDR(start)) | L3_PROT; 129 if (xen_mmu_update(updates, count + 1, NULL, DOMID_SELF) < 0) 130 panic("Unable to update PTE for page table"); 131 count = 0; 132 133 ptl3 = (pte_t *) PFN2ADDR(start_info.ptl0[ptl0_index].frame_address); 134 start++; 135 size--; 136 } 137 138 updates[count].ptr = (uintptr_t) &ptl3[ptl3_index]; 139 updates[count].val = PA2MA(PFN2ADDR(phys)) | L3_PROT; 140 count++; 141 142 if ((count == L3_PT_ENTRIES) || (phys + 1 == start + size)) { 143 if (xen_mmu_update(updates, count, NULL, DOMID_SELF) < 0) 144 panic("Unable to update PTE"); 145 count = 0; 146 } 147 } 148 149 zone_create(start, size, start, 0); 150 last_frame = start + size; 42 /* The only memory zone */ 43 zone_create(meminfo.start, meminfo.size, meminfo.start + meminfo.reserved, 0); 44 frame_mark_unavailable(meminfo.start, meminfo.reserved); 151 45 } 152 46 } -
kernel/arch/xen32/src/xen32.c
re386cbf re12ccc5 37 37 #include <arch/types.h> 38 38 #include <typedefs.h> 39 #include <align.h> 39 40 40 41 #include <arch/pm.h> 41 42 42 43 #include <arch/drivers/xconsole.h> 44 #include <arch/mm/page.h> 43 45 44 46 #include <arch/context.h> … … 61 63 62 64 start_info_t start_info; 65 memzone_t meminfo; 66 67 void arch_pre_main(void) 68 { 69 xen_vm_assist(VMASST_CMD_ENABLE, VMASST_TYPE_WRITABLE_PAGETABLES); 70 71 pte_t pte; 72 memsetb((uintptr_t) &pte, sizeof(pte), 0); 73 74 pte.present = 1; 75 pte.writeable = 1; 76 pte.frame_address = ADDR2PFN((uintptr_t) start_info.shared_info); 77 xen_update_va_mapping(&shared_info, pte, UVMF_INVLPG); 78 79 /* Create identity mapping */ 80 81 meminfo.start = ADDR2PFN(ALIGN_UP(KA2PA(start_info.ptl0), PAGE_SIZE)) + start_info.pt_frames; 82 meminfo.size = start_info.frames - meminfo.start; 83 meminfo.reserved = 0; 84 85 uintptr_t pa; 86 index_t last_ptl0 = 0; 87 for (pa = PFN2ADDR(meminfo.start); pa < PFN2ADDR(meminfo.start + meminfo.size); pa += FRAME_SIZE) { 88 uintptr_t va = PA2KA(pa); 89 90 if ((PTL0_INDEX(va) != last_ptl0) && (GET_PTL1_FLAGS(start_info.ptl0, PTL0_INDEX(va)) & PAGE_NOT_PRESENT)) { 91 /* New page directory entry needed */ 92 uintptr_t tpa = PFN2ADDR(meminfo.start + meminfo.reserved); 93 uintptr_t tva = PA2KA(tpa); 94 95 memsetb(tva, PAGE_SIZE, 0); 96 97 pte_t *tptl3 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(start_info.ptl0, PTL0_INDEX(tva))); 98 SET_FRAME_FLAGS(tptl3, PTL3_INDEX(tva), PAGE_PRESENT); 99 SET_PTL1_ADDRESS(start_info.ptl0, PTL0_INDEX(va), tpa); 100 101 last_ptl0 = PTL0_INDEX(va); 102 meminfo.reserved++; 103 } 104 105 pte_t *ptl3 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(start_info.ptl0, PTL0_INDEX(va))); 106 107 SET_FRAME_ADDRESS(ptl3, PTL3_INDEX(va), pa); 108 SET_FRAME_FLAGS(ptl3, PTL3_INDEX(va), PAGE_PRESENT | PAGE_WRITE); 109 } 110 } 63 111 64 112 void arch_pre_mm_init(void)
Note:
See TracChangeset
for help on using the changeset viewer.