|
|
1.1 ! root 1: .globl entry, __switch_context, __exit_context, halt, init_exceptions ! 2: ! 3: .text ! 4: .align 4 ! 5: ! 6: /* ! 7: * Entry point ! 8: * We start execution from here. ! 9: * It is assumed that CPU is in 32-bit protected mode and ! 10: * all segments are 4GB and base zero (flat model). ! 11: */ ! 12: entry: ! 13: /* Save boot context and switch to our main context. ! 14: * Main context is statically defined in C. ! 15: */ ! 16: pushl %cs ! 17: call __switch_context ! 18: ! 19: /* We get here when the main context switches back to ! 20: * the boot context. ! 21: * Return to previous bootloader. ! 22: */ ! 23: ret ! 24: ! 25: /* ! 26: * Switch execution context ! 27: * This saves registers, segments, and GDT in the stack, then ! 28: * switches the stack, and restores everything from the new stack. ! 29: * This function takes no argument. New stack pointer is ! 30: * taken from global variable __context, and old stack pointer ! 31: * is also saved to __context. This way we can just jump to ! 32: * this routine to get back to the original context. ! 33: * ! 34: * Call this routine with lcall or pushl %cs; call. ! 35: */ ! 36: __switch_context: ! 37: /* Save everything in current stack */ ! 38: pushfl /* 56 */ ! 39: pushl %ds /* 52 */ ! 40: pushl %es /* 48 */ ! 41: pushl %fs /* 44 */ ! 42: pushl %gs /* 40 */ ! 43: pushal /* 8 */ ! 44: subl $8, %esp ! 45: movw %ss, (%esp) /* 0 */ ! 46: sgdt 2(%esp) /* 2 */ ! 47: ! 48: #if 0 ! 49: /* Swap %cs and %eip on the stack, so lret will work */ ! 50: movl 60(%esp), %eax ! 51: xchgl %eax, 64(%esp) ! 52: movl %eax, 60(%esp) ! 53: #endif ! 54: ! 55: /* At this point we don't know if we are on flat segment ! 56: * or relocated. So compute the address offset from %eip. ! 57: * Assuming CS.base==DS.base==SS.base. ! 58: */ ! 59: call 1f ! 60: 1: popl %ebx ! 61: subl $1b, %ebx ! 62: ! 63: /* Interrupts are not allowed... */ ! 64: cli ! 65: ! 66: /* Current context pointer is our stack pointer */ ! 67: movl %esp, %esi ! 68: ! 69: /* Normalize the ctx pointer */ ! 70: subl %ebx, %esi ! 71: ! 72: /* Swap it with new value */ ! 73: xchgl %esi, __context(%ebx) ! 74: ! 75: /* Adjust new ctx pointer for current address offset */ ! 76: addl %ebx, %esi ! 77: ! 78: /* Load new %ss and %esp to temporary */ ! 79: movzwl (%esi), %edx ! 80: movl 20(%esi), %eax ! 81: ! 82: /* Load new GDT */ ! 83: lgdt 2(%esi) ! 84: ! 85: /* Load new stack segment with new GDT */ ! 86: movl %edx, %ss ! 87: ! 88: /* Set new stack pointer, but we have to adjust it because ! 89: * pushal saves %esp value before pushal, and we want the value ! 90: * after pushal. ! 91: */ ! 92: leal -32(%eax), %esp ! 93: ! 94: /* Load the rest from new stack */ ! 95: popal ! 96: popl %gs ! 97: popl %fs ! 98: popl %es ! 99: popl %ds ! 100: popfl ! 101: ! 102: /* Finally, load new %cs and %eip */ ! 103: lret ! 104: ! 105: __exit_context: ! 106: /* Get back to the original context */ ! 107: pushl %cs ! 108: call __switch_context ! 109: ! 110: /* We get here if the other context attempt to switch to this ! 111: * dead context. This should not happen. */ ! 112: ! 113: halt: ! 114: cli ! 115: hlt ! 116: jmp halt ! 117: ! 118: /* ! 119: * initialize exception handler. All exceptions end up in the same ! 120: * C function. ! 121: */ ! 122: ! 123: init_exceptions: ! 124: pushl %ebx ! 125: pushl %edi ! 126: ! 127: /* Initialize the Interrupt Descriptor table */ ! 128: leal _idt, %edi ! 129: leal vec0, %ebx ! 130: movl $(0x08 << 16), %eax /* cs selector */ ! 131: ! 132: 1: movw %bx, %ax ! 133: movl %ebx, %edx ! 134: movw $0x8E00, %dx /* Interrupt gate - dpl=0, present */ ! 135: movl %eax, 0(%edi) ! 136: movl %edx, 4(%edi) ! 137: addl $6, %ebx ! 138: addl $8, %edi ! 139: cmpl $_idt_end, %edi ! 140: jne 1b ! 141: ! 142: /* Load the Interrupt descriptor table */ ! 143: lidt idtarg ! 144: ! 145: movl $0, %eax ! 146: popl %edi ! 147: popl %ebx ! 148: ret ! 149: ! 150: vec0: ! 151: pushl $0 /* error code */ ! 152: pushl $0 /* vector */ ! 153: jmp int_hand ! 154: vec1: ! 155: pushl $0 /* error code */ ! 156: pushl $1 /* vector */ ! 157: jmp int_hand ! 158: ! 159: vec2: ! 160: pushl $0 /* error code */ ! 161: pushl $2 /* vector */ ! 162: jmp int_hand ! 163: ! 164: vec3: ! 165: pushl $0 /* error code */ ! 166: pushl $3 /* vector */ ! 167: jmp int_hand ! 168: ! 169: vec4: ! 170: pushl $0 /* error code */ ! 171: pushl $4 /* vector */ ! 172: jmp int_hand ! 173: ! 174: vec5: ! 175: pushl $0 /* error code */ ! 176: pushl $5 /* vector */ ! 177: jmp int_hand ! 178: ! 179: vec6: ! 180: pushl $0 /* error code */ ! 181: pushl $6 /* vector */ ! 182: jmp int_hand ! 183: vec7: ! 184: pushl $0 /* error code */ ! 185: pushl $7 /* vector */ ! 186: jmp int_hand ! 187: ! 188: vec8: ! 189: /* error code */ ! 190: pushl $8 /* vector */ ! 191: jmp int_hand ! 192: .word 0x9090 ! 193: ! 194: vec9: ! 195: pushl $0 /* error code */ ! 196: pushl $9 /* vector */ ! 197: jmp int_hand ! 198: ! 199: vec10: ! 200: /* error code */ ! 201: pushl $10 /* vector */ ! 202: jmp int_hand ! 203: .word 0x9090 ! 204: ! 205: vec11: ! 206: /* error code */ ! 207: pushl $11 /* vector */ ! 208: jmp int_hand ! 209: .word 0x9090 ! 210: ! 211: vec12: ! 212: /* error code */ ! 213: pushl $12 /* vector */ ! 214: jmp int_hand ! 215: .word 0x9090 ! 216: ! 217: vec13: ! 218: /* error code */ ! 219: pushl $13 /* vector */ ! 220: jmp int_hand ! 221: .word 0x9090 ! 222: ! 223: vec14: ! 224: /* error code */ ! 225: pushl $14 /* vector */ ! 226: jmp int_hand ! 227: .word 0x9090 ! 228: ! 229: vec15: ! 230: pushl $0 /* error code */ ! 231: pushl $15 /* vector */ ! 232: jmp int_hand ! 233: ! 234: vec16: ! 235: pushl $0 /* error code */ ! 236: pushl $16 /* vector */ ! 237: jmp int_hand ! 238: ! 239: vec17: ! 240: /* error code */ ! 241: pushl $17 /* vector */ ! 242: jmp int_hand ! 243: .word 0x9090 ! 244: ! 245: vec18: ! 246: pushl $0 /* error code */ ! 247: pushl $18 /* vector */ ! 248: jmp int_hand ! 249: ! 250: vec19: ! 251: pushl $0 /* error code */ ! 252: pushl $19 /* vector */ ! 253: jmp int_hand ! 254: ! 255: __divide_error: ! 256: pushl $0 /* error code */ ! 257: pushl $20 /* vector */ ! 258: jmp int_hand ! 259: .global __divide_error ! 260: ! 261: int_hand: ! 262: /* At this point on the stack there is: ! 263: * 0(%esp) vector ! 264: * 4(%esp) error code ! 265: * 8(%esp) eip ! 266: * 12(%esp) cs ! 267: * 16(%esp) eflags ! 268: */ ! 269: pushl %edi ! 270: pushl %esi ! 271: pushl %ebp ! 272: /* Original stack pointer */ ! 273: leal 32(%esp), %ebp ! 274: pushl %ebp ! 275: pushl %ebx ! 276: pushl %edx ! 277: pushl %ecx ! 278: pushl %eax ! 279: ! 280: pushl %esp /* Pointer to structure on the stack */ ! 281: ! 282: call x86_exception ! 283: pop %eax /* Drop the pointer */ ! 284: ! 285: popl %eax ! 286: popl %ecx ! 287: popl %edx ! 288: popl %ebx ! 289: popl %ebp /* Ignore saved %esp value */ ! 290: popl %ebp ! 291: popl %esi ! 292: popl %edi ! 293: ! 294: addl $8, %esp /* pop of the vector and error code */ ! 295: ! 296: iret ! 297: ! 298: idtarg: ! 299: .word _idt_end - _idt - 1 /* limit */ ! 300: .long _idt ! 301: .word 0 ! 302: _idt: ! 303: .fill 20, 8, 0 # idt is unitiailzed ! 304: _idt_end: ! 305: ! 306: .globl arch_nvram_size, arch_nvram_get, arch_nvram_put ! 307: arch_nvram_size: ! 308: xor %eax, %eax ! 309: ret ! 310: ! 311: arch_nvram_get: ! 312: ret ! 313: ! 314: arch_nvram_put: ! 315: ret
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.