Raspberry Pi 3, writing to UART results in disordered output

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
almaember
Posts: 6
Joined: Thu Feb 03, 2022 5:43 am

Raspberry Pi 3, writing to UART results in disordered output

Post by almaember »

Hey!

This is my first time posting here, or making an OS, for that matter.
I've been working on a system for Raspberry Pis.
I've mostly followed the RPi Bare bones on the wiki to get an idea of the whole
process, and I have reorganised the code a bit to be more modular.

The issue is, that while running the program, trying to print out a simple
Hello world message, the results end up being mixed up.
I suspect it has something to do with the timing of the printing, since adding
a significant delay between the characters seems to fix the issue.

Here is my code:

Code: Select all

#include <sysdef.h>

#include <Drivers/RasPi/MMIO.h>
#include <Drivers/RasPi/UART.h>

#define RASPI_TYPE 3

static VOID InitEssentialDrivers(void);
static VOID UartPutString(PCSTR szMessage);

VOID KernelMain(DWORD dwDtbPtr32, DWORD dwX1, DWORD dwX2, DWORD dwX3)
{
	BYTE byRead;

	InitEssentialDrivers();

	UartPutString("Hey there\n");

	while (TRUE)
	{
		byRead = UartReadByte();
		UartSendByte(byRead);
	}
}

static VOID UartPutString(PCSTR szMessage)
{
	SIZE i;

	for (i = 0; szMessage[i]; ++i)
	{
		UartSendByte(szMessage[i]);
	}
}

static VOID InitEssentialDrivers(void)
{
	MmioInitDriver(RASPI_TYPE);
	UartInitDriver(RASPI_TYPE);
}
How I ended up with this coding style is a long story, please pretend that it's the normal Unix style instead. What matters here is that BYTE is an unsigned char, SIZE is size_t, PCSTR is const char *, VOID is obviously void, and DWORD is a 64-bit unsigned integer (WORD and HWORD are it's 32 and 16 bit equivalents, respectively).

The other two files, mmio.c and uart.c, are just adaptations of the wiki versions to fit the coding style, so I think it's unlikely that the issue is there.

The system is meant to run on 64-bit (AArch64 based) Raspberry Pis, mine is a Raspberry Pi 3B. However, I didn't yet test this project on the physical hardware, since I don't have the right cables to see the output.

A few examples of unexpected output:

Code: Select all

Hey there
e

Code: Select all

HHey there
eHey thee
r

Code: Select all

HHey there
ehere
00
Thank you for reading! Please help. I tried my best to diagnose this issue, but found nothing.

P.S. One other thing I have noticed is that when you get to the echo part and type too fast, the echo gets messed up too, but permanently so.
When I try to press 'a', for example, I get back an 'a' and another random character, or sometimes too A's. This might be related.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Raspberry Pi 3, writing to UART results in disordered ou

Post by Octocontrabass »

almaember wrote:How I ended up with this coding style is a long story,
If you were to summarize it in one word, would that word be "Microsoft"? :wink:

Anyway, the boot stub on the wiki is suspicious. The official stub code parks three of the four cores, but the stub on the wiki seems to assume the firmware has already parked those three cores. The behavior you're seeing seems pretty consistent with multiple cores running the same code at the same time...
almaember
Posts: 6
Joined: Thu Feb 03, 2022 5:43 am

Re: Raspberry Pi 3, writing to UART results in disordered ou

Post by almaember »

If you were to summarize it in one word, would that word be "Microsoft"? :wink:
I never worked at Microsoft, actually, nor for any Windows software company. Or anybody, for that matter. I wasn't alive for long enough. It originated as a joke, but I think it's kinda neat, actually.
Anyway, the boot stub on the wiki is suspicious. The official stub code parks three of the four cores, but the stub on the wiki seems to assume the firmware has already parked those three cores. The behavior you're seeing seems pretty consistent with multiple cores running the same code at the same time...
The wiki seems to claim that control is transferred from that stub. So that code is meant to run before the stub on the wiki?

EDIT: Thinking about that, it's unlikely. I'll just shut off the other cores and be happy :mrgreen:

Thinking about it, it may be related to me using -kernel flag with QEMU, instead of a full disk image (since the firmware files aren't there
unlike in the disk image). I'll try building a disk image with everything and see what happens.

EDIT 2: Can you give me some pointers? None of the guides, or the reference, that I found seems to mention how to achieve that. I tried to find out how to detect the current core/machine thread but I didn't find anything worthwhile (and even if I did, it was for AArch32).
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Raspberry Pi 3, writing to UART results in disordered ou

Post by Octocontrabass »

almaember wrote:It originated as a joke, but I think it's kinda neat, actually.
So it's just a coincidence that Microsoft uses the exact same type definitions?
almaember wrote:The wiki seems to claim that control is transferred from that stub. So that code is meant to run before the stub on the wiki?
The stub on the wiki is a simpler version of the official boot stub. The official boot stub sets up several things that aren't strictly necessary, so the author of the code on the wiki tried to remove the unnecessary parts.
almaember wrote:Can you give me some pointers? None of the guides, or the reference, that I found seems to mention how to achieve that. I tried to find out how to detect the current core/machine thread but I didn't find anything worthwhile (and even if I did, it was for AArch32).
This link should take you directly to the part of the official boot stub that detects the current core.
almaember
Posts: 6
Joined: Thu Feb 03, 2022 5:43 am

Re: Raspberry Pi 3, writing to UART results in disordered ou

Post by almaember »

The stub on the wiki is a simpler version of the official boot stub. The official boot stub sets up several things that aren't strictly necessary, so the author of the code on the wiki tried to remove the unnecessary parts.
Thanks, I got it now. It seems like this statement is incorrect then: "The environment is set up and execution to _start transferred from armstub8.s." I'd edit it, but I don't know what to put in its place.
This link should take you directly to the part of the official boot stub that detects the current core.
Okay, this seems to be the solution, thank you!
So it's just a coincidence that Microsoft uses the exact same type definitions?
The joke was the reasoning behind using this style, not the style itself. That was indeed heavily modelled Microsoft's. (Although there are small differences, e.g. I use HWORD -> WORD -> DWORD and they use WORD -> DWORD -> QWORD).

EDIT: Remove a bunch of unnecessary empty lines
Post Reply