1 // io/console/vga.cc -- Kernel debugging console for standard VGA text mode
3 // This software is copyright (c) 2006 Scott Wood <scott@buserror.net>.
5 // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 // this software and associated documentation files (the "Software"), to deal with
7 // the Software without restriction, including without limitation the rights to
8 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9 // of the Software, and to permit persons to whom the Software is furnished to do
10 // so, subject to the following condition:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
23 #include <System/IO.h>
24 #include <kern/kernel.h>
25 #include <kern/console.h>
26 #include <kern/notifier.h>
28 #include <kern/libc.h>
29 #include <kern/addrs.h>
30 #include <util/lock.h>
32 void vga_write(char *str);
36 class VGA : public Console {
40 unsigned long io_base;
46 void putc(int ch, int attr)
50 pos -= pos % line_width;
51 } else if (ch == '\r') {
52 pos -= pos % line_width;
54 // Use ll_swap_le16 rather than store_le16 in the hopes
55 // that the compiler can simply change the shifts around
56 // rather than assembling it one way and then ll_swapping.
58 // It's done as one atomic store rather than two single
59 // byte writes (which would eliminate endianness concerns)
60 // to eliminate the possibility of a race where the video
61 // card reads a character before its attribute has been
64 mem_base[pos++] = ll_swap_le16(ch | (attr << 8));
67 if (pos >= lines * line_width) {
70 // FIXME: until memcpy is more than a stupid byte-at-a-time
71 // loop, this could race with the video card.
73 memcpy(mem_base, mem_base + line_width,
74 line_width * (lines - 1) * sizeof(u16));
76 for (int i = 0; i < line_width; i++)
77 mem_base[pos + i] = ll_swap_le16(' ' | (7 << 8));
84 pos = (u16)ll_in_8(0x3d5) << 8;
86 pos |= ll_in_8(0x3d5);
92 ll_out_8(0x3d5, pos >> 8);
94 ll_out_8(0x3d5, pos & 0xff);
98 #include <servers/io/console/vga/IO/Console/VGA.h>
104 // FIXME: should be PCI mem space, not phys mem.
105 mem_base = (u16 *)Arch::phys_to_kvirt(0xb8000);
112 primary_console = this;
115 void write(Array<octet> buf, u64 *LEN)
117 if (!valid_size_t(*LEN))
118 /* throw something */
124 /* throw something */
127 Lock::AutoSpinLockRecIRQ autolock(lock);
130 for (size_t i = 0; i < len; i++)
136 void write_async(Array<octet> buf, u64 len, Notifier notifier)
139 io_notify(notifier, len, io_result::Success);
143 // Use a static constructor, so that it can be used before
144 // memory management is up and running.
150 #include <servers/io/console/vga/footer.cc>