The Pedigree Project  0.1
Bios.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "pedigree/kernel/machine/x86_common/Bios.h"
21 #include "pedigree/kernel/Log.h"
22 #include "pedigree/kernel/debugger/commands/../../core/BootIO.h"
23 #include "pedigree/kernel/panic.h"
24 #include "pedigree/kernel/processor/Processor.h"
25 #include "pedigree/kernel/processor/ProcessorInformation.h"
26 #include "pedigree/kernel/processor/VirtualAddressSpace.h"
27 #include "pedigree/kernel/utilities/StaticString.h"
28 #include "pedigree/kernel/utilities/utility.h"
29 #include "x86emu/x86emu.h"
30 #include <stdarg.h>
31 
32 extern BootIO bootIO;
33 
35 
36 extern "C" int abs(int i);
37 extern "C" void sscanf(void);
38 
39 u8 rdb(u32 addr)
40 {
41  return *reinterpret_cast<u8 *>(addr);
42 }
43 u16 rdw(u32 addr)
44 {
45  return *reinterpret_cast<u16 *>(addr);
46 }
47 u32 rdl(u32 addr)
48 {
49  return *reinterpret_cast<u32 *>(addr);
50 }
51 void wrb(u32 addr, u8 val)
52 {
53  *reinterpret_cast<u8 *>(addr) = val;
54 }
55 void wrw(u32 addr, u16 val)
56 {
57  *reinterpret_cast<u16 *>(addr) = val;
58 }
59 void wrl(u32 addr, u32 val)
60 {
61  *reinterpret_cast<u32 *>(addr) = val;
62 }
63 
64 static u8 inb(X86EMU_pioAddr addr)
65 {
66  uint8_t ret;
67  asm volatile("inb %1, %0" : "=a"(ret) : "dN"(addr));
68  return ret;
69 }
70 static u16 inw(X86EMU_pioAddr addr)
71 {
72  uint16_t ret;
73  asm volatile("inw %1, %0" : "=a"(ret) : "dN"(addr));
74  return ret;
75 }
76 static u32 inl(X86EMU_pioAddr addr)
77 {
78  uint32_t ret;
79  asm volatile("inl %1, %0" : "=a"(ret) : "dN"(addr));
80  return ret;
81 }
82 static void outb(X86EMU_pioAddr addr, u8 val)
83 {
84  asm volatile("outb %1, %0" : : "dN"(addr), "a"(val));
85 }
86 static void outw(X86EMU_pioAddr addr, u16 val)
87 {
88  asm volatile("outw %1, %0" : : "dN"(addr), "a"(val));
89 }
90 static void outl(X86EMU_pioAddr addr, u32 val)
91 {
92  asm volatile("outl %1, %0" : : "dN"(addr), "a"(val));
93 }
94 
95 extern "C" int abs(int i)
96 {
97  return (i > 0) ? i : -i;
98 }
99 
100 extern "C" int exit(int code) NORETURN;
101 int exit(int)
102 {
103  panic("bios: exit()");
104 }
105 
106 extern "C" void sscanf()
107 {
108 }
109 
110 extern "C" void printk(const char *fmt, ...) USED;
111 extern "C" void printk(const char *fmt, ...)
112 {
113  HugeStaticString buf2;
114  char buf[1024];
115 
116  va_list args;
117  int i;
118 
119  va_start(args, fmt);
120  i = VStringFormat(buf, fmt, args);
121  va_end(args);
122 
123  buf[i] = '\0';
124  buf2.clear();
125  buf2 += buf;
126 
127  bootIO.write(buf2, BootIO::White, BootIO::Black);
128 }
129 
130 Bios::Bios() : mallocLoc(0x8000)
131 {
132  X86EMU_memFuncs mf;
133  mf.rdb = &rdb;
134  mf.rdw = &rdw;
135  mf.rdl = &rdl;
136  mf.wrb = &wrb;
137  mf.wrw = &wrw;
138  mf.wrl = &wrl;
139  X86EMU_pioFuncs iof;
140  iof.inb = &inb;
141  iof.inw = &inw;
142  iof.inl = &inl;
143  iof.outb = &outb;
144  iof.outw = &outw;
145  iof.outl = &outl;
146 
147  ByteSet(&M, 0, sizeof(M));
148  M.x86.debug = 0;
149  M.x86.mode = 0;
150  ByteSet(reinterpret_cast<void *>(0x7C00), 0xF4, 0x100);
151 
152  X86EMU_setupMemFuncs(&mf);
153  X86EMU_setupPioFuncs(&iof);
154  M.x86.R_SS = 0x0000;
155  M.x86.R_SP = 0x7F00;
156  M.x86.R_IP = 0x7C00; // Set IP to 0x7C00 as there are 0xF4's there which
157  // will halt the emulation.
158  M.x86.R_CS = 0x0000;
159 }
160 
161 Bios::~Bios()
162 {
163 }
164 
165 uintptr_t Bios::malloc(int n)
166 {
167  uintptr_t loc = mallocLoc;
168  mallocLoc += n;
169  return loc;
170 }
171 
172 void Bios::executeInterrupt(int interrupt)
173 {
174  bool bInterrupts = Processor::getInterrupts();
176 
177  // Switch into the kernel address space before we do anything here.
178  // We would prefer to persist the original mapping in the kernel, than
179  // continuously map in the low MB (creating page tables and the like)
180  // over and over again...
181  VirtualAddressSpace &va = Processor::information().getVirtualAddressSpace();
183  if (&va != &kernva)
185 
186  // We need to check if lower memory is identity mapped properly here.
187  // If it isn't, we can't call the BIOS!
188  if (!kernva.isMapped(0x00000000))
189  {
190  // We have to map it!
191  for (physical_uintptr_t i = 0; i < 0x100; i++)
192  {
193  if (!kernva.map(
194  i * 0x1000, reinterpret_cast<void *>(i * 0x1000),
197  ERROR("BIOS: Map failed at " << Hex << i * 0x1000 << "!");
198  }
199  }
200 
201  X86EMU_prepareForInt(interrupt);
202  X86EMU_exec();
203 
204  // Switch back to the old address space.
205  if (&va != &kernva)
207 
208  Processor::setInterrupts(bInterrupts);
209 }
210 
211 void Bios::setAx(int n)
212 {
213  M.x86.R_AX = n;
214 }
215 void Bios::setBx(int n)
216 {
217  M.x86.R_BX = n;
218 }
219 void Bios::setCx(int n)
220 {
221  M.x86.R_CX = n;
222 }
223 void Bios::setDx(int n)
224 {
225  M.x86.R_DX = n;
226 }
227 void Bios::setDi(int n)
228 {
229  M.x86.R_DI = n;
230 }
231 void Bios::setEs(int n)
232 {
233  M.x86.R_ES = n;
234 }
235 
237 {
238  return M.x86.R_AX;
239 }
241 {
242  return M.x86.R_BX;
243 }
245 {
246  return M.x86.R_CX;
247 }
249 {
250  return M.x86.R_DX;
251 }
253 {
254  return M.x86.R_DI;
255 }
257 {
258  return M.x86.R_ES;
259 }
void setCx(int n)
Definition: Bios.cc:219
static Bios m_Instance
Definition: Bios.h:83
static bool getInterrupts()
EXPORTED_PUBLIC void write(T &str, Colour foreColour, Colour backColour)
int getDi()
Definition: Bios.cc:252
virtual bool isMapped(void *virtualAddress)=0
virtual bool map(physical_uintptr_t physicalAddress, void *virtualAddress, size_t flags)=0
void setAx(int n)
Definition: Bios.cc:211
static EXPORTED_PUBLIC VirtualAddressSpace & getKernelAddressSpace()
void executeInterrupt(int interrupt)
Definition: Bios.cc:172
static ProcessorInformation & information()
Definition: Processor.cc:45
static void switchAddressSpace(VirtualAddressSpace &AddressSpace)
int getEs()
Definition: Bios.cc:256
void setDx(int n)
Definition: Bios.cc:223
Definition: Log.h:136
Definition: Bios.h:28
int getAx()
Definition: Bios.cc:236
static void setInterrupts(bool bEnable)
void setBx(int n)
Definition: Bios.cc:215
int getDx()
Definition: Bios.cc:248
int getBx()
Definition: Bios.cc:240
uintptr_t malloc(int n)
Definition: Bios.cc:165
#define ERROR(text)
Definition: Log.h:82
uintptr_t mallocLoc
Definition: Bios.h:80
void EXPORTED_PUBLIC panic(const char *msg) NORETURN
Definition: panic.cc:121
int getCx()
Definition: Bios.cc:244
void setDi(int n)
Definition: Bios.cc:227
Definition: BootIO.h:36
void setEs(int n)
Definition: Bios.cc:231
Bios()
Definition: Bios.cc:130