The Pedigree Project  0.1
kernel/machine/ppc_common/Vga.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 "Vga.h"
21 #include "Font.c"
22 #include "pedigree/kernel/machine/openfirmware/Device.h"
23 #include "pedigree/kernel/machine/openfirmware/OpenFirmware.h"
24 #include "pedigree/kernel/processor/PhysicalMemoryManager.h"
25 #include "pedigree/kernel/processor/VirtualAddressSpace.h"
26 #include "pedigree/kernel/utilities/utility.h"
27 
28 PPCVga::PPCVga()
29  : m_Framebuffer("VGA framebuffer"), m_pFramebuffer(0), m_Width(0),
30  m_Height(0), m_Depth(0), m_Stride(0)
31 {
32 }
33 
34 PPCVga::~PPCVga()
35 {
36 }
37 
39 {
40  // Firstly get the screen device.
41  OFDevice screen(OpenFirmware::instance().findDevice("screen"));
42 
43  // Get the 'chosen' device.
44  OFDevice chosen(OpenFirmware::instance().findDevice("/chosen"));
45 
46  // Get the (physical) framebuffer address.
47  OFParam physFbAddr = screen.getProperty("address");
48 
49  PhysicalMemoryManager &physicalMemoryManager =
51  if (!physicalMemoryManager.allocateRegion(
52  m_Framebuffer, 0x01000000 / 0x1000,
58  reinterpret_cast<uintptr_t>(physFbAddr)))
59  {
60  // Panic! but we have no way of indicating failure to the user! argh!!
61  for (;;)
62  ;
63  return;
64  }
65 
67  reinterpret_cast<uint8_t *>(m_Framebuffer.virtualAddress());
68 
69  // Create a mapping with OpenFirmware.
71  // mmu.executeMethod("map", 4,
72  // reinterpret_cast<OFParam>(0x6a),
73  // / reinterpret_cast<OFParam>(0x01000000),
74  // // static_cast<OFParam>(m_pFramebuffer),
75  // physF//bAddr); // 0x6a = Uncached.
76 
77  // Find the device width, height and depth.
78  m_Width = reinterpret_cast<uint32_t>(screen.getProperty("width"));
79  m_Height = reinterpret_cast<uint32_t>(screen.getProperty("height"));
80  m_Depth = reinterpret_cast<uint32_t>(screen.getProperty("depth"));
81  m_Stride = reinterpret_cast<uint32_t>(screen.getProperty("linebytes"));
82 
83  if (m_Depth == 8)
84  {
85  for (int i = 0; i < 16; i++)
86  m_pColours[i] = i;
87  }
88  else if (m_Depth == 16)
89  {
90  m_pColours[0] = RGB_16(0x00, 0x00, 0x00); // Black
91  m_pColours[1] = RGB_16(0x00, 0x00, 0x99); // Blue
92  m_pColours[2] = RGB_16(0x00, 0x99, 0x00); // Green
93  m_pColours[3] = RGB_16(0x00, 0x99, 0x99); // Cyan
94  m_pColours[4] = RGB_16(0x99, 0x00, 0x00); // Red
95  m_pColours[5] = RGB_16(0x99, 0x00, 0x99); // Magenta
96  m_pColours[6] = RGB_16(0x99, 0x66, 0x00); // Brown
97  m_pColours[7] = RGB_16(0xBB, 0xBB, 0xBB); // Light grey
98  m_pColours[8] = RGB_16(0x99, 0x99, 0x99); // Dark grey
99  m_pColours[9] = RGB_16(0x00, 0x00, 0xFF); // Light blue
100  m_pColours[10] = RGB_16(0x00, 0xFF, 0x00); // Light green
101  m_pColours[11] = RGB_16(0x00, 0xFF, 0xFF); // Light cyan
102  m_pColours[12] = RGB_16(0xFF, 0x00, 0x00); // Light red
103  m_pColours[13] = RGB_16(0xFF, 0x00, 0xFF); // Light magenta
104  m_pColours[14] = RGB_16(0xFF, 0xFF, 0x00); // Light brown / yellow
105  m_pColours[15] = RGB_16(0xFF, 0xFF, 0xFF); // White
106  m_Stride /= 2; // 16bpp = 2 bytes per pixel.
107  }
108 
109  // Clear the text framebuffer.
110  uint16_t clear = ' ';
111  for (unsigned int i = 0;
112  i < (m_Width / FONT_WIDTH) * (m_Height / FONT_HEIGHT); i++)
113  {
114  m_pTextBuffer[i] = clear;
115  }
116 
117  // Clear the graphics framebuffer.
118  uint16_t *p16Fb = reinterpret_cast<uint16_t *>(m_pFramebuffer);
119  uint32_t *p32Fb = reinterpret_cast<uint32_t *>(m_pFramebuffer);
120  for (unsigned int i = 0; i < m_Stride * m_Height; i++)
121  {
122  switch (m_Depth)
123  {
124  case 8:
125  m_pFramebuffer[i] = 0x00;
126  break;
127  case 16:
128  p16Fb[i] = 0x0000;
129  break;
130  case 32:
131  p32Fb[i] = 0x00000000;
132  break;
133  }
134  }
135 }
136 
137 void PPCVga::pokeBuffer(uint8_t *pBuffer, size_t nBufLen)
138 {
139  uint16_t *pBuffer16 = reinterpret_cast<uint16_t *>(pBuffer);
140  // Refresh screen.
141  for (unsigned int i = 0; i < (m_Width / FONT_WIDTH); i++)
142  {
143  for (unsigned int j = 0; j < (m_Height / FONT_HEIGHT); j++)
144  {
145  int idx = j * (m_Width / FONT_WIDTH) + i;
146  if ((pBuffer16 == m_pTextBuffer) ||
147  (pBuffer16[idx] != m_pTextBuffer[idx]))
148  {
149  m_pTextBuffer[idx] = pBuffer16[idx];
150  uint16_t ch = m_pTextBuffer[j * (m_Width / FONT_WIDTH) + i];
151  unsigned int fg, bg;
152  fg = m_pColours[(ch >> 8) & 0xF];
153  bg = m_pColours[(ch >> 12) & 0xF];
154  putChar(ch & 0xFF, i * FONT_WIDTH, j * FONT_HEIGHT, fg, bg);
155  }
156  }
157  }
158 }
159 
160 void PPCVga::peekBuffer(uint8_t *pBuffer, size_t nBufLen)
161 {
162  MemoryCopy(pBuffer, m_pTextBuffer, nBufLen);
163 }
164 
165 void PPCVga::putChar(char c, int x, int y, unsigned int f, unsigned int b)
166 {
167  int idx = static_cast<int>(c) * FONT_HEIGHT;
168  uint16_t *p16Fb = reinterpret_cast<uint16_t *>(m_pFramebuffer);
169  uint32_t *p32Fb = reinterpret_cast<uint32_t *>(m_pFramebuffer);
170  for (int i = 0; i < FONT_HEIGHT; i++)
171  {
172  unsigned char row = ppc_font[idx + i];
173  for (int j = 0; j < FONT_WIDTH; j++)
174  {
175  unsigned int col;
176  if ((row & (0x80 >> j)) != 0)
177  {
178  col = f;
179  }
180  else
181  {
182  col = b;
183  }
184 
185  if (m_Depth == 8)
186  m_pFramebuffer[y * m_Stride + i * m_Stride + x + j] =
187  col & 0xFF;
188  else if (m_Depth == 16)
189  p16Fb[y * m_Stride + i * m_Stride + x + j] = col & 0xFFFF;
190  else
191  p32Fb[y * m_Stride + i * m_Stride + x + j] = col;
192  }
193  }
194 }
static PhysicalMemoryManager & instance()
static OpenFirmware & instance()
Definition: OpenFirmware.h:45
virtual void pokeBuffer(uint8_t *pBuffer, size_t nBufLen)
virtual void peekBuffer(uint8_t *pBuffer, size_t nBufLen)
uint8_t * m_pFramebuffer
virtual bool allocateRegion(MemoryRegion &Region, size_t cPages, size_t pageConstraints, size_t Flags, physical_uintptr_t start=-1)=0
void * virtualAddress() const
Definition: MemoryRegion.cc:39