1/*
2 * Copyright 2021, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "FwCfg.h"
8
9#include <stdlib.h>
10#include <string.h>
11#include <malloc.h>
12
13#include <ByteOrder.h>
14#include <Htif.h>
15#include <KernelExport.h>
16
17#include "graphics.h"
18
19
20FwCfgRegs *volatile gFwCfgRegs = NULL;
21
22
23namespace FwCfg {
24
25void
26Select(uint16_t selector)
27{
28	// GCC, why are you so crazy?
29	// gFwCfgRegs->selector = B_BENDIAN_TO_HOST_INT16(selector);
30	*(uint16*)0x10100008 = B_BENDIAN_TO_HOST_INT16(selector);
31}
32
33
34void
35DmaOp(uint8_t *bytes, size_t count, uint32_t op)
36{
37	__attribute__ ((aligned (8))) FwCfgDmaAccess volatile dma;
38	dma.control = B_HOST_TO_BENDIAN_INT32(1 << op);
39	dma.length = B_HOST_TO_BENDIAN_INT32(count);
40	dma.address = B_HOST_TO_BENDIAN_INT64((addr_t)bytes);
41	// gFwCfgRegs->dmaAdr = B_HOST_TO_BENDIAN_INT64((addr_t)&dma);
42	*(uint64*)0x10100010 = B_HOST_TO_BENDIAN_INT64((addr_t)&dma);
43	while (uint32_t control = B_BENDIAN_TO_HOST_INT32(dma.control) != 0) {
44		if (((1 << fwCfgDmaFlagsError) & control) != 0)
45			abort();
46	}
47}
48
49
50void
51ReadBytes(uint8_t *bytes, size_t count)
52{
53	DmaOp(bytes, count, fwCfgDmaFlagsRead);
54}
55
56
57void
58WriteBytes(uint8_t *bytes, size_t count)
59{
60	DmaOp(bytes, count, fwCfgDmaFlagsWrite);
61}
62
63
64uint8_t  Read8 () {uint8_t  val; ReadBytes(          &val, sizeof(val)); return val;}
65uint16_t Read16() {uint16_t val; ReadBytes((uint8_t*)&val, sizeof(val)); return val;}
66uint32_t Read32() {uint32_t val; ReadBytes((uint8_t*)&val, sizeof(val)); return val;}
67uint64_t Read64() {uint64_t val; ReadBytes((uint8_t*)&val, sizeof(val)); return val;}
68
69
70void
71ListDir()
72{
73	uint32_t count = B_BENDIAN_TO_HOST_INT32(Read32());
74	dprintf("count: %" B_PRIu32 "\n", count);
75	for (uint32_t i = 0; i < count; i++) {
76		FwCfgFile file;
77		ReadBytes((uint8_t*)&file, sizeof(file));
78		file.size = B_BENDIAN_TO_HOST_INT32(file.size);
79		file.select = B_BENDIAN_TO_HOST_INT16(file.select);
80		file.reserved = B_BENDIAN_TO_HOST_INT16(file.reserved);
81		dprintf("\n");
82		dprintf("size: %" B_PRIu32 "\n", file.size);
83		dprintf("select: %" B_PRIu32 "\n", file.select);
84		dprintf("reserved: %" B_PRIu32 "\n", file.reserved);
85		dprintf("name: %s\n", file.name);
86	}
87}
88
89
90bool
91ThisFile(FwCfgFile& file, uint16_t dir, const char *name)
92{
93	Select(dir);
94	uint32_t count = B_BENDIAN_TO_HOST_INT32(Read32());
95	for (uint32_t i = 0; i < count; i++) {
96		ReadBytes((uint8_t*)&file, sizeof(file));
97		file.size = B_BENDIAN_TO_HOST_INT32(file.size);
98		file.select = B_BENDIAN_TO_HOST_INT16(file.select);
99		file.reserved = B_BENDIAN_TO_HOST_INT16(file.reserved);
100		if (strcmp(file.name, name) == 0)
101			return true;
102	}
103	return false;
104}
105
106
107void
108InitFramebuffer()
109{
110	FwCfgFile file;
111	if (!ThisFile(file, fwCfgSelectFileDir, "etc/ramfb")) {
112		dprintf("[!] ramfb not found\n");
113		return;
114	}
115	dprintf("file.select: %" B_PRIu16 "\n", file.select);
116
117	RamFbCfg cfg;
118	uint32_t width = 1024, height = 768;
119
120	gFramebuf.colors = (uint32_t*)malloc(4*width*height);
121	gFramebuf.stride = width;
122	gFramebuf.width = width;
123	gFramebuf.height = height;
124
125	cfg.addr = B_HOST_TO_BENDIAN_INT64((size_t)gFramebuf.colors);
126	cfg.fourcc = B_HOST_TO_BENDIAN_INT32(ramFbFormatXrgb8888);
127	cfg.flags = B_HOST_TO_BENDIAN_INT32(0);
128	cfg.width = B_HOST_TO_BENDIAN_INT32(width);
129	cfg.height = B_HOST_TO_BENDIAN_INT32(height);
130	cfg.stride = B_HOST_TO_BENDIAN_INT32(4 * width);
131	Select(file.select);
132	WriteBytes((uint8_t*)&cfg, sizeof(cfg));
133}
134
135
136void
137Init()
138{
139	dprintf("gFwCfgRegs: 0x%08" B_PRIx64 "\n", (addr_t)gFwCfgRegs);
140	if (gFwCfgRegs == NULL)
141		return;
142	Select(fwCfgSelectSignature);
143	dprintf("fwCfgSelectSignature: 0x%08" B_PRIx32 "\n", Read32());
144	Select(fwCfgSelectId);
145	dprintf("fwCfgSelectId: : 0x%08" B_PRIx32 "\n", Read32());
146	Select(fwCfgSelectFileDir);
147	ListDir();
148	InitFramebuffer();
149}
150
151
152};
153