blob: 828be1459d026b1b6fa6e1b91a80f9804845d55f [file] [log] [blame]
Kevin O'Connorf076a3e2008-02-25 22:25:15 -05001// 16bit code to load disk image and start system boot.
2//
3// Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
4// Copyright (C) 2002 MandrakeSoft S.A.
5//
6// This file may be distributed under the terms of the GNU GPLv3 license.
7
8#include "types.h" // VISIBLE
9#include "util.h" // irq_enable
10#include "biosvar.h" // struct bregs
11#include "farptr.h" // SET_SEG
12
13static inline void
14__call_irq(u8 nr)
15{
16 asm volatile("int %0" : : "N" (nr));
17}
18
19static inline u32
20call_irq(u8 nr, struct bregs *callregs)
21{
22 u32 flags;
23 asm volatile(
24 // Save current registers
25 "pushal\n"
26 // Pull in calling registers.
27 "movl 0x04(%%eax), %%edi\n"
28 "movl 0x08(%%eax), %%esi\n"
29 "movl 0x0c(%%eax), %%ebp\n"
30 "movl 0x14(%%eax), %%ebx\n"
31 "movl 0x18(%%eax), %%edx\n"
32 "movl 0x1c(%%eax), %%ecx\n"
33 "movl 0x20(%%eax), %%eax\n"
34 // Invoke interrupt
35 "int %1\n"
36 // Restore registers
37 "popal\n"
38 // Exract flags
39 "pushfw\n"
40 "popl %%eax\n"
41 : "=a" (flags): "N" (nr), "a" (callregs), "m" (*callregs));
42 return flags;
43}
44
45static void
46print_boot_failure()
47{
48 bprintf(0, "Boot failed\n");
49}
50
51static void
52try_boot()
53{
54 // XXX - assume floppy
55 u16 bootseg = 0x07c0;
56 u8 bootdrv = 0;
57
58 // Read sector
59 struct bregs cr;
60 memset(&cr, 0, sizeof(cr));
61 cr.dl = bootdrv;
62 SET_SEG(ES, bootseg);
63 cr.bx = 0;
64 cr.ah = 2;
65 cr.al = 1;
66 cr.ch = 0;
67 cr.cl = 1;
68 cr.dh = 0;
69 u32 status = call_irq(0x13, &cr);
70
71 if (status & F_CF) {
72 print_boot_failure();
73 return;
74 }
75
76 u16 bootip = (bootseg & 0x0fff) << 4;
77 bootseg &= 0xf000;
78
79 u32 segoff = (bootseg << 16) | bootip;
80 asm volatile (
81 "pushf\n"
82 "pushl %0\n"
83 "movb %b1, %%dl\n"
84 // Set the magic number in ax and the boot drive in dl.
85 "movw $0xaa55, %%ax\n"
86 // Zero some of the other registers.
87 "xorw %%bx, %%bx\n"
88 "movw %%bx, %%ds\n"
89 "movw %%bx, %%es\n"
90 "movw %%bx, %%bp\n"
91 // Go!
92 "iretw\n"
93 : : "r" (segoff), "ri" (bootdrv));
94}
95
96// Boot Failure recovery: try the next device.
97void VISIBLE
98handle_18(struct bregs *regs)
99{
100 debug_enter(regs);
101 try_boot();
102}
103
104// INT 19h Boot Load Service Entry Point
105void VISIBLE
106handle_19(struct bregs *regs)
107{
108 debug_enter(regs);
109 try_boot();
110}
111
112// Callback from 32bit entry - start boot process
113void VISIBLE
114begin_boot()
115{
116 irq_enable();
117 __call_irq(0x19);
118}