itszor / gcc-vc4 Goto Github PK
View Code? Open in Web Editor NEWPort of GCC to the VideoCore4 processor.
License: GNU General Public License v2.0
Port of GCC to the VideoCore4 processor.
License: GNU General Public License v2.0
https://github.com/littlekernel/lk/blob/master/external/lib/fdt/fdt.c#L153-L205
the above code, with a small patch:
diff --git a/external/lib/fdt/fdt.c b/external/lib/fdt/fdt.c
index c28fcc11..f0dba57e 100644
--- a/external/lib/fdt/fdt.c
+++ b/external/lib/fdt/fdt.c
@@ -7,6 +7,7 @@
#include <fdt.h>
#include <libfdt.h>
+#include <stdio.h>
#include "libfdt_internal.h"
@@ -165,8 +166,10 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
offset += FDT_TAGSIZE;
*nextoffset = -FDT_ERR_BADSTRUCTURE;
+ printf("tag is %d\n", tag);
switch (tag) {
case FDT_BEGIN_NODE:
+ puts("begin node");
/* skip name */
do {
p = fdt_offset_ptr(fdt, offset++, 1);
@@ -176,6 +179,7 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
break;
case FDT_PROP:
+ puts("prop");
lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
if (!can_assume(VALID_DTB) && !lenp)
return FDT_END; /* premature end */
@@ -191,9 +195,13 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
case FDT_END:
case FDT_END_NODE:
case FDT_NOP:
+ puts("end, endnode, or nop");
break;
+ case 0:
+ //puts("wut");
default:
+ puts("default");
return FDT_END;
}
winds up malfunctioning in the weirdest of ways:
tag is 1
tag is 0
default
setupInterArchDtb():113 error -11 FDT_ERR_BADSTRUCTURE
it reports that tag is 1 (FDT_BEGIN_NODE) but never says begin node
the generated asm is:
// call printf on the current tag, which is in r6
c4009570: 61 40 mov r1,r6
c4009572: 00 e8 94 58 01 c4 mov r0,0xc4015894
c4009578: 80 90 6c 1a bl c400ca50 <printf>
// the switch only handles 1 and up, to shift it down
c400957c: 5a c0 7f 37 add lr,r6,-1
c4009580: 40 c1 48 d7 cmp lr,8
// if (lr > 8) then goto default
// so if (tag > 9), which is FDT_END
c4009584: 00 98 80 00 bhi c4009684 <fdt_next_tag+0x160>
// lr must be a number from 0 to 8 inclusive, what follows is an uint16_t[8] of offsets
c4009588: 9a 00 switch lr
c400958a: 05 68
c400958c: 19 68
c400958e: 7d 7d
c4009590: 7d 7d
c4009592: 68 00
c4009594: 00 e8 a0 58 01 c4 mov r0,0xc40158a0
c400959a: 80 90 14 1a bl c400c9c2 <puts>
after annotating the asm, i notice the problem
this should be a switch.b lr
, followed by an uint8_t[8] of offsets, but it somehow turned into a switch lr
for extra confusion, it seems only ghidra shows the difference between 8bit and 16bit switch statements
the gcc/binutils toolchain disassembles both of them identically!
0xa0 0x00
, is switch r0
0x80 0x00
, is switch.b r0
manually decoding the suspect asm, i can confirm the first byte is 0x80 | 0x1a
, and 0x1a is the reg# for LR
so this is indeed a switch.b lr
so how is it malfunctioning?
how should it be fixed?
What is the correct target triplet for this processor on GNU/Linux? I searched and experimented but could not find it.
static inline void
arch_interrupt_save(spin_lock_saved_state_t *statep, spin_lock_save_flags_t flags) {
spin_lock_saved_state_t state = 0;
if (!arch_ints_disabled()) {
state |= SPIN_LOCK_STATE_RESTORE_IRQ;
arch_disable_ints();
}
*statep = state;
}
uint32_t mailbox_fifo_pop(void) {
uint32_t result;
retry:
event_wait(&fifo.event);
spin_lock_saved_state_t state;
spin_lock_irqsave(&fifo.lock, state);
if (fifo.tail != fifo.head) {
result = fifo.buf[fifo.tail];
fifo.tail = modpow2(fifo.tail + 1, fifo.len_pow2);
if (fifo.tail == fifo.head) {
// we've emptied the buffer, unsignal the event
event_unsignal(&fifo.event);
}
} else {
spin_unlock_irqrestore(&fifo.lock, state);
goto retry;
}
spin_unlock_irqrestore(&fifo.lock, state);
return result;
}
results in:
/run/user/1000/ccD2bh6D.s:177: Error: operand out of range (-65 not between -64 and 63)
ive seen this before, but forgot to file an issue, i think its an off by one, with gcc and binutils not agreeing on the bounds
i think the problem is the goto retry
and the previous code being just the wrong length
It fails at the end of first stage bootstrapping.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.