xref: /haiku/src/system/boot/platform/riscv/FwCfg.cpp (revision 9e25244c5e9051f6cd333820d6332397361abd6c)
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 
20 FwCfgRegs *volatile gFwCfgRegs = NULL;
21 
22 
23 namespace FwCfg {
24 
25 void
26 Select(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 
34 void
35 DmaOp(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 
50 void
51 ReadBytes(uint8_t *bytes, size_t count)
52 {
53 	DmaOp(bytes, count, fwCfgDmaFlagsRead);
54 }
55 
56 
57 void
58 WriteBytes(uint8_t *bytes, size_t count)
59 {
60 	DmaOp(bytes, count, fwCfgDmaFlagsWrite);
61 }
62 
63 
64 uint8_t  Read8 () {uint8_t  val; ReadBytes(          &val, sizeof(val)); return val;}
65 uint16_t Read16() {uint16_t val; ReadBytes((uint8_t*)&val, sizeof(val)); return val;}
66 uint32_t Read32() {uint32_t val; ReadBytes((uint8_t*)&val, sizeof(val)); return val;}
67 uint64_t Read64() {uint64_t val; ReadBytes((uint8_t*)&val, sizeof(val)); return val;}
68 
69 
70 void
71 ListDir()
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 
90 bool
91 ThisFile(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 
107 void
108 InitFramebuffer()
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 
136 void
137 Init()
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