1/*-
2 * Copyright (C) 2010 Nathan Whitehorn
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
23 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include <sys/cdefs.h>
27__FBSDID("$FreeBSD$");
28
29#include <stand.h>
30#include "bootstrap.h"
31#include "font.h"
32#include "lv1call.h"
33#include "ps3.h"
34
35#define FONT_SIZE 14
36#define FONT dflt_font_14
37#define XMARGIN 40
38#define YMARGIN 30
39#define BG_COLOR 0x00000000
40#define FG_COLOR 0xffffffff
41
42#define FB_SIZE	(16*1024*1024)
43uint64_t fb_paddr = 0;
44uint32_t *fb_vaddr;
45
46int fb_width, fb_height;
47int x, y;
48
49static void ps3cons_probe(struct console *cp);
50static int ps3cons_init(int arg);
51static void ps3cons_putchar(int c);
52static int ps3cons_getchar();
53static int ps3cons_poll();
54
55struct console ps3console = {
56	"ps3",
57	"Playstation 3 Framebuffer",
58	0,
59	ps3cons_probe,
60	ps3cons_init,
61	ps3cons_putchar,
62	ps3cons_getchar,
63	ps3cons_poll,
64};
65
66static void
67ps3cons_probe(struct console *cp)
68{
69	/* XXX: Get from HV */
70	fb_width = 720;
71	fb_height = 480;
72
73	cp->c_flags |= C_PRESENTIN|C_PRESENTOUT;
74}
75
76static int
77ps3cons_init(int arg)
78{
79	uint64_t fbhandle, fbcontext;
80	int i;
81
82	lv1_gpu_open(0);
83	lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET,
84	    0,0,0,0);
85	lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET,
86	    0,0,1,0);
87	lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
88	    0,L1GPU_DISPLAY_SYNC_VSYNC,0,0);
89	lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
90	    1,L1GPU_DISPLAY_SYNC_VSYNC,0,0);
91	lv1_gpu_memory_allocate(FB_SIZE, 0, 0, 0, 0, &fbhandle, &fb_paddr);
92	lv1_gpu_context_allocate(fbhandle, 0, &fbcontext);
93
94	lv1_gpu_context_attribute(fbcontext,
95	    L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 0, 0, 0, 0);
96	lv1_gpu_context_attribute(fbcontext,
97	    L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 1, 0, 0, 0);
98
99	fb_vaddr = ps3mmu_mapdev(fb_paddr, FB_SIZE);
100
101	x = y = 0;
102
103	/* Blank console */
104	for (i = 0; i < fb_width*fb_height; i++)
105		fb_vaddr[i] = BG_COLOR;
106
107	return (0);
108}
109
110static void
111ps3cons_putchar(int c)
112{
113	uint32_t fg, bg;
114	uint32_t *addr;
115	int i, j, k;
116	u_char *p;
117
118	fg = FG_COLOR;
119	bg = BG_COLOR;
120
121	switch (c) {
122	case '\0':
123		break;
124	case '\r':
125		x = 0;
126		break;
127	case '\n':
128		y += FONT_SIZE;
129		break;
130	case '\b':
131		x = max(0, x - 8);
132		break;
133	default:
134		/* Wrap long lines */
135		if (x + XMARGIN + FONT_SIZE > fb_width - XMARGIN) {
136			y += FONT_SIZE;
137			x = 0;
138		}
139
140		if (y + YMARGIN + FONT_SIZE > fb_height - YMARGIN)
141			y = 0;
142
143		addr = fb_vaddr + (y + YMARGIN)*fb_width + (x + XMARGIN);
144		p = FONT + c*FONT_SIZE;
145
146		for (i = 0; i < FONT_SIZE; i++) {
147			for (j = 0, k = 7; j < 8; j++, k--) {
148				if ((p[i] & (1 << k)) == 0)
149					*(addr + j) = bg;
150				else
151					*(addr + j) = fg;
152			}
153
154			addr += fb_width;
155		}
156
157		x += 8;
158		break;
159	}
160}
161
162static int
163ps3cons_getchar()
164{
165	return (-1);
166}
167
168static int
169ps3cons_poll()
170{
171	return (0);
172}
173
174