diff --git a/src/arch/x86_64/boot/trap.asm b/src/arch/x86_64/boot/trap.asm new file mode 100644 index 0000000..46e250a --- /dev/null +++ b/src/arch/x86_64/boot/trap.asm @@ -0,0 +1,1327 @@ +# handler +section .text +vector0: + push 0 + push 0 + jmp __alltraps +vector1: + push 0 + push 1 + jmp __alltraps +vector2: + push 0 + push 2 + jmp __alltraps +vector3: + push 0 + push 3 + jmp __alltraps +vector4: + push 0 + push 4 + jmp __alltraps +vector5: + push 0 + push 5 + jmp __alltraps +vector6: + push 0 + push 6 + jmp __alltraps +vector7: + push 0 + push 7 + jmp __alltraps +vector8: + push 8 + jmp __alltraps +vector9: + push 9 + jmp __alltraps +vector10: + push 10 + jmp __alltraps +vector11: + push 11 + jmp __alltraps +vector12: + push 12 + jmp __alltraps +vector13: + push 13 + jmp __alltraps +vector14: + push 14 + jmp __alltraps +vector15: + push 0 + push 15 + jmp __alltraps +vector16: + push 0 + push 16 + jmp __alltraps +vector17: + push 17 + jmp __alltraps +vector18: + push 0 + push 18 + jmp __alltraps +vector19: + push 0 + push 19 + jmp __alltraps +vector20: + push 0 + push 20 + jmp __alltraps +vector21: + push 0 + push 21 + jmp __alltraps +vector22: + push 0 + push 22 + jmp __alltraps +vector23: + push 0 + push 23 + jmp __alltraps +vector24: + push 0 + push 24 + jmp __alltraps +vector25: + push 0 + push 25 + jmp __alltraps +vector26: + push 0 + push 26 + jmp __alltraps +vector27: + push 0 + push 27 + jmp __alltraps +vector28: + push 0 + push 28 + jmp __alltraps +vector29: + push 0 + push 29 + jmp __alltraps +vector30: + push 0 + push 30 + jmp __alltraps +vector31: + push 0 + push 31 + jmp __alltraps +vector32: + push 0 + push 32 + jmp __alltraps +vector33: + push 0 + push 33 + jmp __alltraps +vector34: + push 0 + push 34 + jmp __alltraps +vector35: + push 0 + push 35 + jmp __alltraps +vector36: + push 0 + push 36 + jmp __alltraps +vector37: + push 0 + push 37 + jmp __alltraps +vector38: + push 0 + push 38 + jmp __alltraps +vector39: + push 0 + push 39 + jmp __alltraps +vector40: + push 0 + push 40 + jmp __alltraps +vector41: + push 0 + push 41 + jmp __alltraps +vector42: + push 0 + push 42 + jmp __alltraps +vector43: + push 0 + push 43 + jmp __alltraps +vector44: + push 0 + push 44 + jmp __alltraps +vector45: + push 0 + push 45 + jmp __alltraps +vector46: + push 0 + push 46 + jmp __alltraps +vector47: + push 0 + push 47 + jmp __alltraps +vector48: + push 0 + push 48 + jmp __alltraps +vector49: + push 0 + push 49 + jmp __alltraps +vector50: + push 0 + push 50 + jmp __alltraps +vector51: + push 0 + push 51 + jmp __alltraps +vector52: + push 0 + push 52 + jmp __alltraps +vector53: + push 0 + push 53 + jmp __alltraps +vector54: + push 0 + push 54 + jmp __alltraps +vector55: + push 0 + push 55 + jmp __alltraps +vector56: + push 0 + push 56 + jmp __alltraps +vector57: + push 0 + push 57 + jmp __alltraps +vector58: + push 0 + push 58 + jmp __alltraps +vector59: + push 0 + push 59 + jmp __alltraps +vector60: + push 0 + push 60 + jmp __alltraps +vector61: + push 0 + push 61 + jmp __alltraps +vector62: + push 0 + push 62 + jmp __alltraps +vector63: + push 0 + push 63 + jmp __alltraps +vector64: + push 0 + push 64 + jmp __alltraps +vector65: + push 0 + push 65 + jmp __alltraps +vector66: + push 0 + push 66 + jmp __alltraps +vector67: + push 0 + push 67 + jmp __alltraps +vector68: + push 0 + push 68 + jmp __alltraps +vector69: + push 0 + push 69 + jmp __alltraps +vector70: + push 0 + push 70 + jmp __alltraps +vector71: + push 0 + push 71 + jmp __alltraps +vector72: + push 0 + push 72 + jmp __alltraps +vector73: + push 0 + push 73 + jmp __alltraps +vector74: + push 0 + push 74 + jmp __alltraps +vector75: + push 0 + push 75 + jmp __alltraps +vector76: + push 0 + push 76 + jmp __alltraps +vector77: + push 0 + push 77 + jmp __alltraps +vector78: + push 0 + push 78 + jmp __alltraps +vector79: + push 0 + push 79 + jmp __alltraps +vector80: + push 0 + push 80 + jmp __alltraps +vector81: + push 0 + push 81 + jmp __alltraps +vector82: + push 0 + push 82 + jmp __alltraps +vector83: + push 0 + push 83 + jmp __alltraps +vector84: + push 0 + push 84 + jmp __alltraps +vector85: + push 0 + push 85 + jmp __alltraps +vector86: + push 0 + push 86 + jmp __alltraps +vector87: + push 0 + push 87 + jmp __alltraps +vector88: + push 0 + push 88 + jmp __alltraps +vector89: + push 0 + push 89 + jmp __alltraps +vector90: + push 0 + push 90 + jmp __alltraps +vector91: + push 0 + push 91 + jmp __alltraps +vector92: + push 0 + push 92 + jmp __alltraps +vector93: + push 0 + push 93 + jmp __alltraps +vector94: + push 0 + push 94 + jmp __alltraps +vector95: + push 0 + push 95 + jmp __alltraps +vector96: + push 0 + push 96 + jmp __alltraps +vector97: + push 0 + push 97 + jmp __alltraps +vector98: + push 0 + push 98 + jmp __alltraps +vector99: + push 0 + push 99 + jmp __alltraps +vector100: + push 0 + push 100 + jmp __alltraps +vector101: + push 0 + push 101 + jmp __alltraps +vector102: + push 0 + push 102 + jmp __alltraps +vector103: + push 0 + push 103 + jmp __alltraps +vector104: + push 0 + push 104 + jmp __alltraps +vector105: + push 0 + push 105 + jmp __alltraps +vector106: + push 0 + push 106 + jmp __alltraps +vector107: + push 0 + push 107 + jmp __alltraps +vector108: + push 0 + push 108 + jmp __alltraps +vector109: + push 0 + push 109 + jmp __alltraps +vector110: + push 0 + push 110 + jmp __alltraps +vector111: + push 0 + push 111 + jmp __alltraps +vector112: + push 0 + push 112 + jmp __alltraps +vector113: + push 0 + push 113 + jmp __alltraps +vector114: + push 0 + push 114 + jmp __alltraps +vector115: + push 0 + push 115 + jmp __alltraps +vector116: + push 0 + push 116 + jmp __alltraps +vector117: + push 0 + push 117 + jmp __alltraps +vector118: + push 0 + push 118 + jmp __alltraps +vector119: + push 0 + push 119 + jmp __alltraps +vector120: + push 0 + push 120 + jmp __alltraps +vector121: + push 0 + push 121 + jmp __alltraps +vector122: + push 0 + push 122 + jmp __alltraps +vector123: + push 0 + push 123 + jmp __alltraps +vector124: + push 0 + push 124 + jmp __alltraps +vector125: + push 0 + push 125 + jmp __alltraps +vector126: + push 0 + push 126 + jmp __alltraps +vector127: + push 0 + push 127 + jmp __alltraps +vector128: + push 0 + push 128 + jmp __alltraps +vector129: + push 0 + push 129 + jmp __alltraps +vector130: + push 0 + push 130 + jmp __alltraps +vector131: + push 0 + push 131 + jmp __alltraps +vector132: + push 0 + push 132 + jmp __alltraps +vector133: + push 0 + push 133 + jmp __alltraps +vector134: + push 0 + push 134 + jmp __alltraps +vector135: + push 0 + push 135 + jmp __alltraps +vector136: + push 0 + push 136 + jmp __alltraps +vector137: + push 0 + push 137 + jmp __alltraps +vector138: + push 0 + push 138 + jmp __alltraps +vector139: + push 0 + push 139 + jmp __alltraps +vector140: + push 0 + push 140 + jmp __alltraps +vector141: + push 0 + push 141 + jmp __alltraps +vector142: + push 0 + push 142 + jmp __alltraps +vector143: + push 0 + push 143 + jmp __alltraps +vector144: + push 0 + push 144 + jmp __alltraps +vector145: + push 0 + push 145 + jmp __alltraps +vector146: + push 0 + push 146 + jmp __alltraps +vector147: + push 0 + push 147 + jmp __alltraps +vector148: + push 0 + push 148 + jmp __alltraps +vector149: + push 0 + push 149 + jmp __alltraps +vector150: + push 0 + push 150 + jmp __alltraps +vector151: + push 0 + push 151 + jmp __alltraps +vector152: + push 0 + push 152 + jmp __alltraps +vector153: + push 0 + push 153 + jmp __alltraps +vector154: + push 0 + push 154 + jmp __alltraps +vector155: + push 0 + push 155 + jmp __alltraps +vector156: + push 0 + push 156 + jmp __alltraps +vector157: + push 0 + push 157 + jmp __alltraps +vector158: + push 0 + push 158 + jmp __alltraps +vector159: + push 0 + push 159 + jmp __alltraps +vector160: + push 0 + push 160 + jmp __alltraps +vector161: + push 0 + push 161 + jmp __alltraps +vector162: + push 0 + push 162 + jmp __alltraps +vector163: + push 0 + push 163 + jmp __alltraps +vector164: + push 0 + push 164 + jmp __alltraps +vector165: + push 0 + push 165 + jmp __alltraps +vector166: + push 0 + push 166 + jmp __alltraps +vector167: + push 0 + push 167 + jmp __alltraps +vector168: + push 0 + push 168 + jmp __alltraps +vector169: + push 0 + push 169 + jmp __alltraps +vector170: + push 0 + push 170 + jmp __alltraps +vector171: + push 0 + push 171 + jmp __alltraps +vector172: + push 0 + push 172 + jmp __alltraps +vector173: + push 0 + push 173 + jmp __alltraps +vector174: + push 0 + push 174 + jmp __alltraps +vector175: + push 0 + push 175 + jmp __alltraps +vector176: + push 0 + push 176 + jmp __alltraps +vector177: + push 0 + push 177 + jmp __alltraps +vector178: + push 0 + push 178 + jmp __alltraps +vector179: + push 0 + push 179 + jmp __alltraps +vector180: + push 0 + push 180 + jmp __alltraps +vector181: + push 0 + push 181 + jmp __alltraps +vector182: + push 0 + push 182 + jmp __alltraps +vector183: + push 0 + push 183 + jmp __alltraps +vector184: + push 0 + push 184 + jmp __alltraps +vector185: + push 0 + push 185 + jmp __alltraps +vector186: + push 0 + push 186 + jmp __alltraps +vector187: + push 0 + push 187 + jmp __alltraps +vector188: + push 0 + push 188 + jmp __alltraps +vector189: + push 0 + push 189 + jmp __alltraps +vector190: + push 0 + push 190 + jmp __alltraps +vector191: + push 0 + push 191 + jmp __alltraps +vector192: + push 0 + push 192 + jmp __alltraps +vector193: + push 0 + push 193 + jmp __alltraps +vector194: + push 0 + push 194 + jmp __alltraps +vector195: + push 0 + push 195 + jmp __alltraps +vector196: + push 0 + push 196 + jmp __alltraps +vector197: + push 0 + push 197 + jmp __alltraps +vector198: + push 0 + push 198 + jmp __alltraps +vector199: + push 0 + push 199 + jmp __alltraps +vector200: + push 0 + push 200 + jmp __alltraps +vector201: + push 0 + push 201 + jmp __alltraps +vector202: + push 0 + push 202 + jmp __alltraps +vector203: + push 0 + push 203 + jmp __alltraps +vector204: + push 0 + push 204 + jmp __alltraps +vector205: + push 0 + push 205 + jmp __alltraps +vector206: + push 0 + push 206 + jmp __alltraps +vector207: + push 0 + push 207 + jmp __alltraps +vector208: + push 0 + push 208 + jmp __alltraps +vector209: + push 0 + push 209 + jmp __alltraps +vector210: + push 0 + push 210 + jmp __alltraps +vector211: + push 0 + push 211 + jmp __alltraps +vector212: + push 0 + push 212 + jmp __alltraps +vector213: + push 0 + push 213 + jmp __alltraps +vector214: + push 0 + push 214 + jmp __alltraps +vector215: + push 0 + push 215 + jmp __alltraps +vector216: + push 0 + push 216 + jmp __alltraps +vector217: + push 0 + push 217 + jmp __alltraps +vector218: + push 0 + push 218 + jmp __alltraps +vector219: + push 0 + push 219 + jmp __alltraps +vector220: + push 0 + push 220 + jmp __alltraps +vector221: + push 0 + push 221 + jmp __alltraps +vector222: + push 0 + push 222 + jmp __alltraps +vector223: + push 0 + push 223 + jmp __alltraps +vector224: + push 0 + push 224 + jmp __alltraps +vector225: + push 0 + push 225 + jmp __alltraps +vector226: + push 0 + push 226 + jmp __alltraps +vector227: + push 0 + push 227 + jmp __alltraps +vector228: + push 0 + push 228 + jmp __alltraps +vector229: + push 0 + push 229 + jmp __alltraps +vector230: + push 0 + push 230 + jmp __alltraps +vector231: + push 0 + push 231 + jmp __alltraps +vector232: + push 0 + push 232 + jmp __alltraps +vector233: + push 0 + push 233 + jmp __alltraps +vector234: + push 0 + push 234 + jmp __alltraps +vector235: + push 0 + push 235 + jmp __alltraps +vector236: + push 0 + push 236 + jmp __alltraps +vector237: + push 0 + push 237 + jmp __alltraps +vector238: + push 0 + push 238 + jmp __alltraps +vector239: + push 0 + push 239 + jmp __alltraps +vector240: + push 0 + push 240 + jmp __alltraps +vector241: + push 0 + push 241 + jmp __alltraps +vector242: + push 0 + push 242 + jmp __alltraps +vector243: + push 0 + push 243 + jmp __alltraps +vector244: + push 0 + push 244 + jmp __alltraps +vector245: + push 0 + push 245 + jmp __alltraps +vector246: + push 0 + push 246 + jmp __alltraps +vector247: + push 0 + push 247 + jmp __alltraps +vector248: + push 0 + push 248 + jmp __alltraps +vector249: + push 0 + push 249 + jmp __alltraps +vector250: + push 0 + push 250 + jmp __alltraps +vector251: + push 0 + push 251 + jmp __alltraps +vector252: + push 0 + push 252 + jmp __alltraps +vector253: + push 0 + push 253 + jmp __alltraps +vector254: + push 0 + push 254 + jmp __alltraps +vector255: + push 0 + push 255 + jmp __alltraps + +__alltraps: + push rax + push rcx + push rdx + push rdi + push rsi + push r8 + push r9 + push r10 + push r11 + + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + + mov rdi, rsp + + ; extern fn rust_trap(rsp) -> rsp + extern rust_trap + call rust_trap + + mov rsp, rax + + pop r15 + pop r14 + pop r13 + pop r12 + pop rbp + pop rbx + + pop r11 + pop r10 + pop r9 + pop r8 + pop rsi + pop rdi + pop rdx + pop rcx + pop rax + + ; pop trap_num, error_code + add rsp, 16 + + iretq + +# vector table +.rodata +global __vectors +__vectors: + dq vector0 + dq vector1 + dq vector2 + dq vector3 + dq vector4 + dq vector5 + dq vector6 + dq vector7 + dq vector8 + dq vector9 + dq vector10 + dq vector11 + dq vector12 + dq vector13 + dq vector14 + dq vector15 + dq vector16 + dq vector17 + dq vector18 + dq vector19 + dq vector20 + dq vector21 + dq vector22 + dq vector23 + dq vector24 + dq vector25 + dq vector26 + dq vector27 + dq vector28 + dq vector29 + dq vector30 + dq vector31 + dq vector32 + dq vector33 + dq vector34 + dq vector35 + dq vector36 + dq vector37 + dq vector38 + dq vector39 + dq vector40 + dq vector41 + dq vector42 + dq vector43 + dq vector44 + dq vector45 + dq vector46 + dq vector47 + dq vector48 + dq vector49 + dq vector50 + dq vector51 + dq vector52 + dq vector53 + dq vector54 + dq vector55 + dq vector56 + dq vector57 + dq vector58 + dq vector59 + dq vector60 + dq vector61 + dq vector62 + dq vector63 + dq vector64 + dq vector65 + dq vector66 + dq vector67 + dq vector68 + dq vector69 + dq vector70 + dq vector71 + dq vector72 + dq vector73 + dq vector74 + dq vector75 + dq vector76 + dq vector77 + dq vector78 + dq vector79 + dq vector80 + dq vector81 + dq vector82 + dq vector83 + dq vector84 + dq vector85 + dq vector86 + dq vector87 + dq vector88 + dq vector89 + dq vector90 + dq vector91 + dq vector92 + dq vector93 + dq vector94 + dq vector95 + dq vector96 + dq vector97 + dq vector98 + dq vector99 + dq vector100 + dq vector101 + dq vector102 + dq vector103 + dq vector104 + dq vector105 + dq vector106 + dq vector107 + dq vector108 + dq vector109 + dq vector110 + dq vector111 + dq vector112 + dq vector113 + dq vector114 + dq vector115 + dq vector116 + dq vector117 + dq vector118 + dq vector119 + dq vector120 + dq vector121 + dq vector122 + dq vector123 + dq vector124 + dq vector125 + dq vector126 + dq vector127 + dq vector128 + dq vector129 + dq vector130 + dq vector131 + dq vector132 + dq vector133 + dq vector134 + dq vector135 + dq vector136 + dq vector137 + dq vector138 + dq vector139 + dq vector140 + dq vector141 + dq vector142 + dq vector143 + dq vector144 + dq vector145 + dq vector146 + dq vector147 + dq vector148 + dq vector149 + dq vector150 + dq vector151 + dq vector152 + dq vector153 + dq vector154 + dq vector155 + dq vector156 + dq vector157 + dq vector158 + dq vector159 + dq vector160 + dq vector161 + dq vector162 + dq vector163 + dq vector164 + dq vector165 + dq vector166 + dq vector167 + dq vector168 + dq vector169 + dq vector170 + dq vector171 + dq vector172 + dq vector173 + dq vector174 + dq vector175 + dq vector176 + dq vector177 + dq vector178 + dq vector179 + dq vector180 + dq vector181 + dq vector182 + dq vector183 + dq vector184 + dq vector185 + dq vector186 + dq vector187 + dq vector188 + dq vector189 + dq vector190 + dq vector191 + dq vector192 + dq vector193 + dq vector194 + dq vector195 + dq vector196 + dq vector197 + dq vector198 + dq vector199 + dq vector200 + dq vector201 + dq vector202 + dq vector203 + dq vector204 + dq vector205 + dq vector206 + dq vector207 + dq vector208 + dq vector209 + dq vector210 + dq vector211 + dq vector212 + dq vector213 + dq vector214 + dq vector215 + dq vector216 + dq vector217 + dq vector218 + dq vector219 + dq vector220 + dq vector221 + dq vector222 + dq vector223 + dq vector224 + dq vector225 + dq vector226 + dq vector227 + dq vector228 + dq vector229 + dq vector230 + dq vector231 + dq vector232 + dq vector233 + dq vector234 + dq vector235 + dq vector236 + dq vector237 + dq vector238 + dq vector239 + dq vector240 + dq vector241 + dq vector242 + dq vector243 + dq vector244 + dq vector245 + dq vector246 + dq vector247 + dq vector248 + dq vector249 + dq vector250 + dq vector251 + dq vector252 + dq vector253 + dq vector254 + dq vector255 diff --git a/src/arch/x86_64/idt/mod.rs b/src/arch/x86_64/idt/mod.rs index b5ba560..80b275c 100644 --- a/src/arch/x86_64/idt/mod.rs +++ b/src/arch/x86_64/idt/mod.rs @@ -11,31 +11,26 @@ pub fn init() { use arch::gdt::DOUBLE_FAULT_IST_INDEX; let mut idt = Idt::new(); - idt[T_BRKPT].set_handler_fn(breakpoint); - idt[T_PGFLT].set_handler_fn(page_fault); - idt[T_GPFLT].set_handler_fn(general_protection_fault); - idt[T_ILLOP].set_handler_fn(invalid_opcode); - idt[T_IRQ0 + IRQ_COM1].set_handler_fn(com1); - idt[T_IRQ0 + IRQ_COM2].set_handler_fn(com2); - idt[T_IRQ0 + IRQ_KBD].set_handler_fn(keyboard); - idt[T_IRQ0 + IRQ_TIMER].set_handler_fn(timer); + for i in 0u8..=255 { + idt[i].set_handler_fn(unsafe { __vectors[i as usize] }); + } - idt[T_SWITCH_TOU].set_handler_fn(to_user); - idt[T_SWITCH_TOK].set_handler_fn(to_kernel) - .set_flags(IdtFlags::PRESENT | IdtFlags::RING_3 | IdtFlags::INTERRUPT); + idt[T_SWITCH_TOK].set_flags(IdtFlags::PRESENT | IdtFlags::RING_3 | IdtFlags::INTERRUPT); // TODO: Enable interrupt during syscall - idt[T_SYSCALL].set_handler_fn(syscall) - .set_flags(IdtFlags::PRESENT | IdtFlags::RING_3 | IdtFlags::INTERRUPT); - idt[0x80].set_handler_fn(syscall32) - .set_flags(IdtFlags::PRESENT | IdtFlags::RING_3 | IdtFlags::INTERRUPT); + idt[T_SYSCALL].set_flags(IdtFlags::PRESENT | IdtFlags::RING_3 | IdtFlags::INTERRUPT); + idt[0x80].set_flags(IdtFlags::PRESENT | IdtFlags::RING_3 | IdtFlags::INTERRUPT); unsafe { - idt[T_DBLFLT].set_handler_fn(double_fault) - .set_stack_index(DOUBLE_FAULT_IST_INDEX as u16); + idt[T_DBLFLT].set_stack_index(DOUBLE_FAULT_IST_INDEX as u16); } idt }); let idt = unsafe{ &*Box::into_raw(idt) }; idt.load(); -} \ No newline at end of file +} + +extern { + //noinspection RsStaticConstNaming + static __vectors: [extern fn(); 256]; +} diff --git a/src/arch/x86_64/interrupt/handler.rs b/src/arch/x86_64/interrupt/handler.rs index cdd3a28..fc76ab2 100644 --- a/src/arch/x86_64/interrupt/handler.rs +++ b/src/arch/x86_64/interrupt/handler.rs @@ -1,45 +1,34 @@ -#[macro_use] -#[path = "./template.rs"] -mod template; -use self::template::*; -pub type TrapFrame = InterruptStackP; - -interrupt_stack!(breakpoint, stack, { +fn breakpoint() { error!("\nEXCEPTION: Breakpoint"); - stack.dump(); -}); +} -interrupt_error_p!(double_fault, stack, { +fn double_fault() { error!("\nEXCEPTION: Double Fault"); - stack.dump(); loop {} -}); +} -interrupt_error_p!(page_fault, stack, { +fn page_fault(tf: &mut TrapFrame) { use x86_64::registers::control_regs::cr2; let addr = cr2().0; - error!("\nEXCEPTION: Page Fault @ {:#x}, code: {:#x}", addr, stack.code); + error!("\nEXCEPTION: Page Fault @ {:#x}, code: {:#x}", addr, tf.error_code); use memory::page_fault_handler; if page_fault_handler(addr) { return; } - stack.dump(); loop {} -}); +} -interrupt_error_p!(general_protection_fault, stack, { +fn general_protection_fault() { error!("\nEXCEPTION: General Protection Fault"); - stack.dump(); loop {} -}); +} -interrupt_stack_p!(invalid_opcode, stack, { +fn invalid_opcode() { error!("\nEXCEPTION: Invalid Opcode"); - stack.dump(); loop {} -}); +} #[cfg(feature = "use_apic")] use arch::driver::apic::ack; @@ -48,63 +37,128 @@ use arch::driver::pic::ack; use super::consts::*; -interrupt!(keyboard, { +fn keyboard() { use arch::driver::keyboard; info!("\nInterupt: Keyboard"); let c = keyboard::get(); info!("Key = '{}' {}", c as u8 as char, c); - ack(IRQ_KBD); - -}); +} -interrupt!(com1, { +fn com1() { use arch::driver::serial::COM1; info!("\nInterupt: COM1"); COM1.lock().receive(); - ack(IRQ_COM1); -}); +} -interrupt!(com2, { +fn com2() { use arch::driver::serial::COM2; info!("\nInterupt: COM2"); COM2.lock().receive(); - ack(IRQ_COM2); -}); +} -interrupt_switch!(timer, stack, rsp, { +fn timer(tf: &mut TrapFrame, rsp: &mut usize) { use process; - process::timer_handler(stack, &mut rsp); - ack(IRQ_TIMER); -}); + process::timer_handler(tf, rsp); +} -interrupt_stack_p!(to_user, stack, { +fn to_user(tf: &mut TrapFrame) { use arch::gdt; info!("\nInterupt: To User"); - let rsp = unsafe{ (stack as *const InterruptStackP).offset(1) } as usize; - gdt::set_ring0_rsp(rsp); - stack.iret.cs = gdt::UCODE_SELECTOR.0 as usize; - stack.iret.ss = gdt::UDATA_SELECTOR.0 as usize; - stack.iret.rflags |= 3 << 12; // 设置EFLAG的I/O特权位,使得在用户态可使用in/out指令 -}); - -interrupt_stack_p!(to_kernel, stack, { -// info!("rsp @ {:#x}", stack as *const _ as usize); + tf.cs = gdt::UCODE_SELECTOR.0 as usize; + tf.ss = gdt::UDATA_SELECTOR.0 as usize; + tf.rflags |= 3 << 12; // 设置EFLAG的I/O特权位,使得在用户态可使用in/out指令 +} + +fn to_kernel(tf: &mut TrapFrame) { use arch::gdt; info!("\nInterupt: To Kernel"); - stack.iret.cs = gdt::KCODE_SELECTOR.0 as usize; - stack.iret.ss = gdt::KDATA_SELECTOR.0 as usize; -}); + tf.cs = gdt::KCODE_SELECTOR.0 as usize; + tf.ss = gdt::KDATA_SELECTOR.0 as usize; +} -interrupt_switch!(syscall, stack, rsp, { - info!("\nInterupt: Syscall {:#x?}", stack.scratch.rax); +fn syscall(tf: &mut TrapFrame, rsp: &mut usize) { + info!("\nInterupt: Syscall {:#x?}", tf.rax); use syscall::syscall; - let ret = syscall(stack, &mut rsp, false); - stack.scratch.rax = ret as usize; -}); + let ret = syscall(tf, rsp, false); + tf.rax = ret as usize; +} -interrupt_switch!(syscall32, stack, rsp, { -// info!("\nInterupt: Syscall {:#x?}", stack.scratch.rax); +fn syscall32(tf: &mut TrapFrame, rsp: &mut usize) { + // info!("\nInterupt: Syscall {:#x?}", tf.rax); use syscall::syscall; - let ret = syscall(stack, &mut rsp, true); - stack.scratch.rax = ret as usize; -}); \ No newline at end of file + let ret = syscall(tf, rsp, true); + tf.rax = ret as usize; +} + +#[no_mangle] +pub extern fn rust_trap(tf: &mut TrapFrame) -> usize { + let mut rsp = tf as *const _ as usize; + + // Dispatch + match tf.trap_num as u8 { + T_BRKPT => breakpoint(), + T_DBLFLT => double_fault(), + T_PGFLT => page_fault(tf), + T_GPFLT => general_protection_fault(), + T_IRQ0...64 => { + let irq = tf.trap_num as u8 - T_IRQ0; + match irq { + IRQ_TIMER => timer(tf, &mut rsp), + IRQ_KBD => keyboard(), + IRQ_COM1 => com1(), + IRQ_COM2 => com2(), + _ => panic!("Invalid IRQ number."), + } + ack(irq); + } + T_SWITCH_TOK => to_kernel(tf), + T_SWITCH_TOU => to_user(tf), + T_SYSCALL => syscall(tf, &mut rsp), + 0x80 => syscall32(tf, &mut rsp), + _ => panic!("Unhandled interrupt {:x}", tf.trap_num), + } + + // Set return rsp if to user + let tf = unsafe { &*(rsp as *const TrapFrame) }; + set_return_rsp(tf); + + rsp +} + +fn set_return_rsp(tf: &TrapFrame) { + use arch::gdt; + use core::mem::size_of; + if tf.cs & 0x3 == 3 { + gdt::set_ring0_rsp(tf as *const _ as usize + size_of::()); + } +} + +#[derive(Debug, Clone, Default)] +pub struct TrapFrame { + pub r15: usize, + pub r14: usize, + pub r13: usize, + pub r12: usize, + pub rbp: usize, + pub rbx: usize, + + pub r11: usize, + pub r10: usize, + pub r9: usize, + pub r8: usize, + pub rsi: usize, + pub rdi: usize, + pub rdx: usize, + pub rcx: usize, + pub rax: usize, + + pub trap_num: usize, + pub error_code: usize, + + pub rip: usize, + pub cs: usize, + pub rflags: usize, + + pub rsp: usize, + pub ss: usize, +} \ No newline at end of file diff --git a/src/arch/x86_64/interrupt/mod.rs b/src/arch/x86_64/interrupt/mod.rs index 2d32fdc..4a74fd7 100644 --- a/src/arch/x86_64/interrupt/mod.rs +++ b/src/arch/x86_64/interrupt/mod.rs @@ -10,21 +10,21 @@ impl TrapFrame { pub fn new_kernel_thread(entry: extern fn(), rsp: usize) -> Self { use arch::gdt; let mut tf = TrapFrame::default(); - tf.iret.cs = gdt::KCODE_SELECTOR.0 as usize; - tf.iret.rip = entry as usize; - tf.iret.ss = gdt::KDATA_SELECTOR.0 as usize; - tf.iret.rsp = rsp; - tf.iret.rflags = 0x282; + tf.cs = gdt::KCODE_SELECTOR.0 as usize; + tf.rip = entry as usize; + tf.ss = gdt::KDATA_SELECTOR.0 as usize; + tf.rsp = rsp; + tf.rflags = 0x282; tf } pub fn new_user_thread(entry_addr: usize, rsp: usize, is32: bool) -> Self { use arch::gdt; let mut tf = TrapFrame::default(); - tf.iret.cs = if is32 { gdt::UCODE32_SELECTOR.0 } else { gdt::UCODE_SELECTOR.0 } as usize; - tf.iret.rip = entry_addr; - tf.iret.ss = if is32 { gdt::UDATA32_SELECTOR.0 } else { gdt::UDATA_SELECTOR.0 } as usize; - tf.iret.rsp = rsp; - tf.iret.rflags = 0x282; + tf.cs = if is32 { gdt::UCODE32_SELECTOR.0 } else { gdt::UCODE_SELECTOR.0 } as usize; + tf.rip = entry_addr; + tf.ss = if is32 { gdt::UDATA32_SELECTOR.0 } else { gdt::UDATA_SELECTOR.0 } as usize; + tf.rsp = rsp; + tf.rflags = 0x282; tf } } diff --git a/src/arch/x86_64/interrupt/template.rs b/src/arch/x86_64/interrupt/template.rs deleted file mode 100644 index 0c639d9..0000000 --- a/src/arch/x86_64/interrupt/template.rs +++ /dev/null @@ -1,452 +0,0 @@ -//! Copy from Redox - -#[allow(dead_code)] -#[repr(packed)] -#[derive(Clone, Default)] -pub struct ScratchRegisters { - pub r11: usize, - pub r10: usize, - pub r9: usize, - pub r8: usize, - pub rsi: usize, - pub rdi: usize, - pub rdx: usize, - pub rcx: usize, - pub rax: usize, -} - -impl ScratchRegisters { - pub fn dump(&self) { - println!("RAX: {:>016X}", { self.rax }); - println!("RCX: {:>016X}", { self.rcx }); - println!("RDX: {:>016X}", { self.rdx }); - println!("RDI: {:>016X}", { self.rdi }); - println!("RSI: {:>016X}", { self.rsi }); - println!("R8: {:>016X}", { self.r8 }); - println!("R9: {:>016X}", { self.r9 }); - println!("R10: {:>016X}", { self.r10 }); - println!("R11: {:>016X}", { self.r11 }); - } -} - -macro_rules! scratch_push { - () => (asm!( - "push rax - push rcx - push rdx - push rdi - push rsi - push r8 - push r9 - push r10 - push r11" - : : : : "intel", "volatile" - )); -} - -macro_rules! scratch_pop { - () => (asm!( - "pop r11 - pop r10 - pop r9 - pop r8 - pop rsi - pop rdi - pop rdx - pop rcx - pop rax" - : : : : "intel", "volatile" - )); -} - -#[allow(dead_code)] -#[repr(packed)] -#[derive(Clone, Default)] -pub struct PreservedRegisters { - pub r15: usize, - pub r14: usize, - pub r13: usize, - pub r12: usize, - pub rbp: usize, - pub rbx: usize, -} - -impl PreservedRegisters { - pub fn dump(&self) { - println!("RBX: {:>016X}", { self.rbx }); - println!("RBP: {:>016X}", { self.rbp }); - println!("R12: {:>016X}", { self.r12 }); - println!("R13: {:>016X}", { self.r13 }); - println!("R14: {:>016X}", { self.r14 }); - println!("R15: {:>016X}", { self.r15 }); - } -} - -macro_rules! preserved_push { - () => (asm!( - "push rbx - push rbp - push r12 - push r13 - push r14 - push r15" - : : : : "intel", "volatile" - )); -} - -macro_rules! preserved_pop { - () => (asm!( - "pop r15 - pop r14 - pop r13 - pop r12 - pop rbp - pop rbx" - : : : : "intel", "volatile" - )); -} - -macro_rules! fs_push { - () => (asm!( - "push fs - mov rax, 0x18 - mov fs, ax" - : : : : "intel", "volatile" - )); -} - -macro_rules! fs_pop { - () => (asm!( - "pop fs" - : : : : "intel", "volatile" - )); -} - -#[allow(dead_code)] -#[repr(packed)] -#[derive(Clone, Default)] -pub struct IretRegisters { - pub rip: usize, - pub cs: usize, - pub rflags: usize, - pub rsp: usize, - pub ss: usize, -} - -impl IretRegisters { - pub fn dump(&self) { - println!("SS: {:>016X}", { self.ss }); - println!("RSP: {:>016X}", { self.rsp }); - println!("RFLAG: {:>016X}", { self.rflags }); - println!("CS: {:>016X}", { self.cs }); - println!("RIP: {:>016X}", { self.rip }); - } -} - -macro_rules! iret { - () => (asm!( - "iretq" - : : : : "intel", "volatile" - )); -} - -/// Create an interrupt function that can safely run rust code -macro_rules! interrupt { - ($name:ident, $func:block) => { - #[naked] - pub unsafe extern fn $name () { - #[inline(never)] - unsafe fn inner() { - $func - } - - // Push scratch registers - scratch_push!(); - fs_push!(); - - // Map kernel -// $crate::arch::x86_64::pti::map(); - - // Call inner rust function - inner(); - - // Unmap kernel -// $crate::arch::x86_64::pti::unmap(); - - // Pop scratch registers and return - fs_pop!(); - scratch_pop!(); - iret!(); - } - }; -} - -#[allow(dead_code)] -#[repr(packed)] -pub struct InterruptStack { - pub fs: usize, - pub scratch: ScratchRegisters, - pub iret: IretRegisters, -} - -impl InterruptStack { - pub fn dump(&self) { - self.iret.dump(); - self.scratch.dump(); - println!("FS: {:>016X}", { self.fs }); - } -} - -macro_rules! interrupt_stack { - ($name:ident, $stack: ident, $func:block) => { - #[naked] - pub unsafe extern fn $name () { - #[inline(never)] - unsafe fn inner($stack: &mut InterruptStack) { - $func - } - - // Push scratch registers - scratch_push!(); - fs_push!(); - - // Get reference to stack variables - let rsp: usize; - asm!("" : "={rsp}"(rsp) : : : "intel", "volatile"); - - // Map kernel -// $crate::arch::x86_64::pti::map(); - - // Call inner rust function - inner(&mut *(rsp as *mut InterruptStack)); - - // Unmap kernel -// $crate::arch::x86_64::pti::unmap(); - - // Pop scratch registers and return - fs_pop!(); - scratch_pop!(); - iret!(); - } - }; -} - -#[allow(dead_code)] -#[repr(packed)] -pub struct InterruptErrorStack { - pub fs: usize, - pub scratch: ScratchRegisters, - pub code: usize, - pub iret: IretRegisters, -} - -impl InterruptErrorStack { - pub fn dump(&self) { - self.iret.dump(); - println!("CODE: {:>016X}", { self.code }); - self.scratch.dump(); - println!("FS: {:>016X}", { self.fs }); - } -} - -macro_rules! interrupt_error { - ($name:ident, $stack:ident, $func:block) => { - #[naked] - pub unsafe extern fn $name () { - #[inline(never)] - unsafe fn inner($stack: &InterruptErrorStack) { - $func - } - - // Push scratch registers - scratch_push!(); - fs_push!(); - - // Get reference to stack variables - let rsp: usize; - asm!("" : "={rsp}"(rsp) : : : "intel", "volatile"); - - // Map kernel -// $crate::arch::x86_64::pti::map(); - - // Call inner rust function - inner(&*(rsp as *const InterruptErrorStack)); - - // Unmap kernel -// $crate::arch::x86_64::pti::unmap(); - - // Pop scratch registers, error code, and return - fs_pop!(); - scratch_pop!(); - asm!("add rsp, 8" : : : : "intel", "volatile"); - iret!(); - } - }; -} - -#[allow(dead_code)] -#[repr(packed)] -#[derive(Clone, Default)] -pub struct InterruptStackP { - pub fs: usize, - pub preserved: PreservedRegisters, - pub scratch: ScratchRegisters, - pub iret: IretRegisters, -} - -impl InterruptStackP { - pub fn dump(&self) { - self.iret.dump(); - self.scratch.dump(); - self.preserved.dump(); - println!("FS: {:>016X}", { self.fs }); - } -} - -use core::fmt::Debug; -use core::fmt::Formatter; -use core::fmt::Error; - -impl Debug for InterruptStackP { - fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { - self.dump(); - Ok(()) - } -} - -macro_rules! interrupt_switch { - ($name:ident, $stack: ident, $rsp: ident, $func:block) => { - #[naked] - pub unsafe extern fn $name () { - // WARNING: Don't do anything outside the inner function. - // rbp is not pointing to kernel stack! - #[inline(never)] - unsafe fn inner($stack: &mut InterruptStackP) -> usize { - let mut $rsp = $stack as *const _ as usize; - $func - - // Set return rsp if to user - use arch::gdt; - use core::mem::size_of; - let tf = &mut *($rsp as *mut TrapFrame); - if tf.iret.cs & 0x3 == 3 { - gdt::set_ring0_rsp($rsp + size_of::()); - } - $rsp - } - - // Push scratch registers - scratch_push!(); - preserved_push!(); - fs_push!(); - - // Get reference to stack variables - let rsp: usize; - asm!("mov rbp, rsp" : "={rsp}"(rsp) : : : "intel", "volatile"); - // "mov rbp, rsp" <-- Fix a lot of bugs! - - // Call inner rust function - let rsp = inner(&mut *(rsp as *mut InterruptStackP)); - asm!("" : : "{rsp}"(rsp) : : "intel", "volatile"); - - // Pop scratch registers and return - fs_pop!(); - preserved_pop!(); - scratch_pop!(); - iret!(); - } - }; -} - -macro_rules! interrupt_stack_p { - ($name:ident, $stack: ident, $func:block) => { - #[naked] - pub unsafe extern fn $name () { - #[inline(never)] - unsafe fn inner($stack: &mut InterruptStackP) { - $func - } - - // Push scratch registers - scratch_push!(); - preserved_push!(); - fs_push!(); - - // Get reference to stack variables - let rsp: usize; - asm!("" : "={rsp}"(rsp) : : : "intel", "volatile"); - - // Map kernel -// $crate::arch::x86_64::pti::map(); - - // Call inner rust function - inner(&mut *(rsp as *mut InterruptStackP)); - - // Unmap kernel -// $crate::arch::x86_64::pti::unmap(); - - // Pop scratch registers and return - fs_pop!(); - preserved_pop!(); - scratch_pop!(); - iret!(); - } - }; -} - -#[allow(dead_code)] -#[repr(packed)] -pub struct InterruptErrorStackP { - pub fs: usize, - pub preserved: PreservedRegisters, - pub scratch: ScratchRegisters, - pub code: usize, - pub iret: IretRegisters, -} - -impl InterruptErrorStackP { - pub fn dump(&self) { - self.iret.dump(); - println!("CODE: {:>016X}", { self.code }); - self.scratch.dump(); - self.preserved.dump(); - println!("FS: {:>016X}", { self.fs }); - } -} - -macro_rules! interrupt_error_p { - ($name:ident, $stack:ident, $func:block) => { - #[naked] - pub unsafe extern fn $name () { - #[inline(never)] - unsafe fn inner($stack: &InterruptErrorStackP) { - $func - } - - // Push scratch registers - scratch_push!(); - preserved_push!(); - fs_push!(); - - // Get reference to stack variables - let rsp: usize; - asm!("" : "={rsp}"(rsp) : : : "intel", "volatile"); - - // Map kernel -// $crate::arch::x86_64::pti::map(); - - // Call inner rust function - inner(&*(rsp as *const InterruptErrorStackP)); - - // Unmap kernel -// $crate::arch::x86_64::pti::unmap(); - - // Pop scratch registers, error code, and return - fs_pop!(); - preserved_pop!(); - scratch_pop!(); - asm!("add rsp, 8" : : : : "intel", "volatile"); - iret!(); - } - }; -} diff --git a/src/lib.rs b/src/lib.rs index 3b45caf..1b3d5f9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -128,6 +128,8 @@ pub extern "C" fn other_main() -> ! { loop {} } +pub use arch::interrupt::handler::rust_trap; + use linked_list_allocator::LockedHeap; /// Global heap allocator diff --git a/src/process/process.rs b/src/process/process.rs index 968e717..f04347d 100644 --- a/src/process/process.rs +++ b/src/process/process.rs @@ -160,7 +160,7 @@ impl Process { // Allocate kernel stack and push trap frame let kstack = mc.alloc_stack(7).unwrap(); let mut tf = tf.clone(); - tf.scratch.rax = 0; // sys_fork return 0 for child + tf.rax = 0; // sys_fork return 0 for child let rsp = kstack.push_at_top(tf); Process { @@ -178,7 +178,7 @@ impl Process { pub fn set_return_value(&self, value: usize) { let tf = unsafe { &mut *(self.rsp as *mut TrapFrame) }; - tf.scratch.rax = value; + tf.rax = value; } pub fn exit_code(&self) -> Option { match self.status { diff --git a/src/syscall.rs b/src/syscall.rs index abaaabc..72d9efa 100644 --- a/src/syscall.rs +++ b/src/syscall.rs @@ -2,16 +2,16 @@ use super::*; use process; use arch::interrupt::TrapFrame; -pub unsafe fn syscall(tf: &TrapFrame, rsp: &mut usize, is32: bool) -> i32 { +pub fn syscall(tf: &TrapFrame, rsp: &mut usize, is32: bool) -> i32 { let id = match is32 { - false => Syscall::Xv6(tf.scratch.rax), - true => Syscall::Ucore(tf.scratch.rax), + false => Syscall::Xv6(tf.rax), + true => Syscall::Ucore(tf.rax), }; let args = match is32 { // For ucore x86 - true => [tf.scratch.rdx, tf.scratch.rcx, tf.preserved.rbx, tf.scratch.rdi, tf.scratch.rsi, 0], + true => [tf.rdx, tf.rcx, tf.rbx, tf.rdi, tf.rsi, 0], // For xv6 x86_64 - false => [tf.scratch.rdi, tf.scratch.rsi, tf.scratch.rdx, tf.scratch.rcx, tf.scratch.r8, tf.scratch.r9], + false => [tf.rdi, tf.rsi, tf.rdx, tf.rcx, tf.r8, tf.r9], }; match id {