Updated the text around Memory and added a section for the firmware / initialization.

This commit is contained in:
Garritt McCune
2025-02-07 16:08:41 -06:00
parent 883c48270f
commit 53962331d5
+13 -20
View File
@@ -1,8 +1,9 @@
\chapter{Introduction} \chapter{Introduction}
This is an attempt to distill what I know about how computers work into some kind of emulator / simulator. I'm curious to see if what I know at the moment is enough to allow me too emulate a general purpose computer. It turns out that it take quite a different skill set compared to writing web or desktop applications. But I realize that, while I understand the concepts that underpin what I do day to day, I don't have an intuitive understanding of the hardware. This has become painfully evident pretty much immediately after I started this project. An ISA should be simple, add, subtract, copy, etc., but then you have to consider the state that the processor will be in after each instruction. This is an attempt to distill what I know about how computers work into some kind of emulator / simulator. I'm curious to see if what I know at the moment is enough to allow me too emulate a general purpose computer. It turns out that it take quite a different skill set compared to writing web or desktop applications. But I realize that, while I understand the concepts that underpin what I do day to day, I don't have an intuitive understanding of the hardware. This has become painfully evident pretty much immediately after I started this project. An ISA should be simple, add, subtract, copy, etc., but then you have to consider the state that the processor will be in after each instruction. This \quotes{little} project will be a specification for a sort of System-on-Chip (SoC) where the CPU, GPU and memory are all inter-connected.
\section{Conventions \& Data Types} \section{Conventions \& Data Types}
This machine is \quotes{little endian} meaning bytes are numbered starting from the least significant byte or the right most byte. Figure \ref{fig:bytelayout} shows how a structure is layed out in memory byte by byte. This machine is \quotes{little endian} meaning bytes are numbered starting from the least significant byte or the right most byte. Figure \ref{fig:bytelayout} shows how a structure is layed out in memory byte by byte.
\begin{figure}[h] \begin{figure}[h]
\label{fig:bytelayout} % https://www.overleaf.com/learn/latex/Referencing_Figures
\begin{tikzpicture} \begin{tikzpicture}
% Row 0 % Row 0
\node [draw, fit={( 0.0, 0.0) ( 2.0, 0.5)}, inner sep=0, label=center:byte 0] (row0b0) {}; \node [draw, fit={( 0.0, 0.0) ( 2.0, 0.5)}, inner sep=0, label=center:byte 0] (row0b0) {};
@@ -38,7 +39,6 @@ This machine is \quotes{little endian} meaning bytes are numbered starting from
\node at (mostbit.west)[left] {Bit Offset}; \node at (mostbit.west)[left] {Bit Offset};
\end{tikzpicture} \end{tikzpicture}
\caption{Layout of a Structure in Memory} \caption{Layout of a Structure in Memory}
\label{fig:bytelayout}
\end{figure} \end{figure}
There are three data types that are understood by this machine: byte, short and word. There are three data types that are understood by this machine: byte, short and word.
@@ -53,6 +53,7 @@ Thirty-two general purpose registers are available for program code to use howev
In addition to the general purpose registers there is also a base pointer (bp), stack pointer (sp) and an instruction pointer (ip). The base pointer and the stack pointer may be set directly using the \hyperref[sec:mov]{mov} instruction, which allows the programmer to set up a stack frame. The instruction pointer can only be set with a branching operation like \hyperref[sec:jmp]{jmp} or a call to a subroutine with the \hyperref[sec:call]{call} instruction. One final register that can only be indirectly set is the \quotes{flags} register. This register, like the others, is one word wide meaning it can store thirty-two flags. Currently only three flags are present, the Zero, Underflow and Overflow flags. These flags are only affected by arithmetic operations and generally read by branching instructions like \hyperref[sec:jmp]{jmp}. In addition to the general purpose registers there is also a base pointer (bp), stack pointer (sp) and an instruction pointer (ip). The base pointer and the stack pointer may be set directly using the \hyperref[sec:mov]{mov} instruction, which allows the programmer to set up a stack frame. The instruction pointer can only be set with a branching operation like \hyperref[sec:jmp]{jmp} or a call to a subroutine with the \hyperref[sec:call]{call} instruction. One final register that can only be indirectly set is the \quotes{flags} register. This register, like the others, is one word wide meaning it can store thirty-two flags. Currently only three flags are present, the Zero, Underflow and Overflow flags. These flags are only affected by arithmetic operations and generally read by branching instructions like \hyperref[sec:jmp]{jmp}.
\begin{figure}[h] \begin{figure}[h]
\label{fig:registerbitlayout} % https://www.overleaf.com/learn/latex/Referencing_Figures
\begin{tikzpicture} \begin{tikzpicture}
%\draw[help lines] (-8,-3) grid (8,3); %\draw[help lines] (-8,-3) grid (8,3);
\node [draw, fit={(-6, 0) (-1, -0.5)}, label=center:r1] (r1) {}; \node [draw, fit={(-6, 0) (-1, -0.5)}, label=center:r1] (r1) {};
@@ -64,29 +65,19 @@ In addition to the general purpose registers there is also a base pointer (bp),
\node [draw, fit={(0, -1.0) (5, -1.5)}, label=center:Base Pointer (ip)] (bp) {}; \node [draw, fit={(0, -1.0) (5, -1.5)}, label=center:Base Pointer (ip)] (bp) {};
\node [draw, fit={(0, -2.0) (5, -2.5)}, label=center:Stack Pointer (ip)] (sp) {}; \node [draw, fit={(0, -2.0) (5, -2.5)}, label=center:Stack Pointer (ip)] (sp) {};
\draw (r1);
\node at (r1.north) [above] {General Purpose}; \node at (r1.north) [above] {General Purpose};
\node at (r1.north west) [above] {31}; \node at (r1.north west) [above] {31};
\node at (r1.north east) [above] {0}; \node at (r1.north east) [above] {0};
\draw (ellipsis);
\draw (r32);
\draw (flags);
\node at (flags.north) [above] {Status Register}; \node at (flags.north) [above] {Status Register};
\node at (flags.north west) [above] {31}; \node at (flags.north west) [above] {31};
\node at (flags.north east) [above] {0}; \node at (flags.north east) [above] {0};
\draw (ip);
\node at (ip.north) [above] {Program Status}; \node at (ip.north) [above] {Program Status};
\node at (ip.north west) [above] {31}; \node at (ip.north west) [above] {31};
\node at (ip.north east) [above] {0}; \node at (ip.north east) [above] {0};
\draw (bp);
\draw (sp);
\end{tikzpicture} \end{tikzpicture}
\caption{Bit Ordering} \caption{Bit Ordering}
\label{fig:registerbitlayout} % https://www.overleaf.com/learn/latex/Referencing_Figures
\end{figure} \end{figure}
\begin{description} \begin{description}
@@ -98,14 +89,14 @@ In addition to the general purpose registers there is also a base pointer (bp),
\end{description} \end{description}
\section{Memory} \section{Memory}
Memory is laid out as a contiguous linear block for a total of 2\textsuperscript{32} bytes of addressable memory. Addressing starts at 0x00000000 and grows downward toward 0xFFFFFFFF as shown in Figure \ref{fig:memoryhighlow}. The figure also shows the direction the stack grows along with the heap, which grows in the opposite direction. Memory is laid out as a contiguous linear block for a total of 2\textsuperscript{32} bytes of addressable memory. Addressing starts at 0x00000000 and grows downward toward 0xFFFFFFFF as shown in Figure \ref{fig:memoryhighlow}. The figure also shows the direction the stack grows along with the heap, which grows in the opposite direction. For a quick reference to the initial mapped memory see Figure \ref{fig:memorymap}.
% How memory mapped I/O works: https://superuser.com/questions/595672/how-is-memory-mapped-to-certain-hardware-how-is-mmio-accomplished-exactly % How memory mapped I/O works: https://superuser.com/questions/595672/how-is-memory-mapped-to-certain-hardware-how-is-mmio-accomplished-exactly
\begin{figure}[h] \begin{figure}[h]
\label{fig:memoryhighlow} % https://www.overleaf.com/learn/latex/Referencing_Figures
\begin{tikzpicture} \begin{tikzpicture}
\node [draw, fit={(0,0) (3, 6)}] (memory) {}; \node [draw, fit={(0,0) (3, 6)}] (memory) {};
\draw (memory);
\node (top) at (memory.north east)[right] {0x00000000}; \node (top) at (memory.north east)[right] {0x00000000};
\node at (memory.south east)[right] {0xFFFFFFFF}; \node at (memory.south east)[right] {0xFFFFFFFF};
@@ -117,24 +108,26 @@ Memory is laid out as a contiguous linear block for a total of 2\textsuperscript
%\draw[dashed] ($(memory.north west)-(0.0,1.5)$) node[left] {0x276100} -- ($(memory.north east)-(0.0,1.5)$) node[midway, above] {VRAM - 3.75MiB}; %\draw[dashed] ($(memory.north west)-(0.0,1.5)$) node[left] {0x276100} -- ($(memory.north east)-(0.0,1.5)$) node[midway, above] {VRAM - 3.75MiB};
\end{tikzpicture} \end{tikzpicture}
\caption{Memory Layout} \caption{Memory Layout}
\label{fig:memoryhighlow} % https://www.overleaf.com/learn/latex/Referencing_Figures
\end{figure} \end{figure}
\subsection{Memory Mapping} \section{Device Initialization \& Firmware}
On initialization the CPU will load firmware from read-only memory, or \quotes{ROM}, starting at address 0xFFDFFFFF and ending at 0xFFFFFFFF. This leaves 2MiB (2,097,152) bytes of memory for the firmware code, barring some form of compression. From there the firmware itself will setup a simple memory map, as shown in Figure \ref{fig:memorymap}. On initialization the CPU will load firmware from read-only memory, or \quotes{ROM}, starting at address 0xFFDFFFFF and ending at 0xFFFFFFFF. From there the firmware will perform basic setup routines like creating the interrupt table, mapping HID and constructing the \quotes{Devicetree}. The Devicetree that is built adheres to the \quotes{Devicetree} specification (\url{https://www.devicetree.org/specifications}) allowing for an agnostic way of providing information about the machine be it to a bootloader or an operating system. Figure \ref{fig:memorymap} shows how the memory is setup after the firmware has completed initialization and proceeds to look for bootable media.
\begin{figure}[h] \begin{figure}[h]
\label{fig:memorymap} % https://www.overleaf.com/learn/latex/Referencing_Figures
\begin{tabularx}{\textwidth}{ | c | c | X | X | } \begin{tabularx}{\textwidth}{ | c | c | X | X | }
\hline \hline
Start & End & Used For & Remark \\ Start & End & Used For & Remark \\
\hline \hline
0x00000000 & 0x000003FC & Interrupt Table & 255 Word Entries \\ 0x00000000 & 0x000003FC & Interrupt Table & 255 Word Entries \\
\hline \hline
0x00000400 & 0x000004FF & Keyboard Buffer & 255 Chars \\ 0x00000400 & 0x002003FC & Devicetree & 2MiB - One Word\\
\hline
0x00200400 & 0x002004FF & Keyboard Buffer & 255 Chars \\
\hline
0x00200500 & 0x002024C0 & Video Buffer & 127 x 64 Col x Row \\
\hline \hline
0xFFDFFFFF & 0xFFFFFFFF & Firmware & 2MiB \\ 0xFFDFFFFF & 0xFFFFFFFF & Firmware & 2MiB \\
\hline \hline
\end{tabularx} \end{tabularx}
\caption{Initial Memory Map} \caption{Initial Memory Map}
\label{fig:memorymap}
\end{figure} \end{figure}