summaryrefslogtreecommitdiffstats
path: root/arch/architecture.dox
blob: 2d2cf05aa7493040ad776e3692e6d91ab5c5765c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/** @page dev_architecture Integrate a new architecture (ARCH)

@section linker_scripts Rules for the generic Linker Script File

Never include an object file by name directly! Linker Script Files defines the
layout, not the content. Content is defined in objecfiles instead.

Don't rely on the given object file order to create your binary @a barebox! This
may work, but is not relyable in all cases (and its a very bad style)!

For the special case some layout contraints exists, use specific section
naming instead. Refer @ref reset_code how to define this specific section.

@section reset_code Bring it up: The Reset Code

The way a CPU wakes up after reset is very specific to its architecture.

For example the ARM architecture starts its reset code at address 0x0000000,
the x86 architecture at 0x000FFFF0, PowerPC at 0x00000100 or 0xFFFFF100.

So for the special reset code on all architectures it must be located at
architecture specific locations within the binary @a barebox image.

All reset code uses section ".text_entry" for its localisation within the
binary @a barebox image. Its up to the linker script file to use this section name
to find the right place in whatever environment and @a barebox sizes.

@code
	.section ".text_entry","ax"
@endcode

@section arch_files List of changes

 - create a new subdirectory in /arch
TODO

*/

/** @page dev_cpu Integrate a new CPU (MACH)

Features required for every CPU:

 - clocksource
 - CPU reset function

@section time_keeping Time keeping

In @a barebox we are using the clocksource mechanism from the Linux Kernel.
This makes it fairly easy to add timer functionality for a new board or
architecture.

Apart from initialization there is only one function to be registerd:
clocksource_read(). This function returns the current value of a free running
counter. Other functions like udelay() and get_time_ns() are derived from this
function. The only thing you have to implement is a clocksource driver and
to register it at runtime.

@code
static uint64_t mycpu_clocksource_read(void)
{
	TODO
}

static struct clocksource cs = {
	.read	= mycpu_clocksource_read,
	.mask	= 0xffffffff,
	.shift	= 10,
};

....
	init_clock(&cs);
....
@endcode

See arch/arm/mach-imx/clocksource.c for an example. clocksource drivers from
the Linux Kernel can be used nearly 1:1, except for the register accesses.

Note: For clocksources the __lshrdi3 symbol is needed. You can find the
function for your architecture in the Linux Kernel or a libc of your choice.

@note @a barebox expects an upward counting counter!

@section reset_function Reset function

TODO

@li @subpage dev_arm_mach
@li @subpage dev_bf_mach
@li @subpage dev_mips_mach
@li @subpage dev_ppc_mach
@li @subpage dev_x86_mach

*/

/** @page io_access_functions I/O access functions

List of functions to be used for hardware register access (I/O).

@section native_access Native IN/OUT access

@note Native means: It uses the same endianess than the CPU.

@subsection single_native_access Single access of various width

The following functions are intended to be used for a single I/O access.

To read a byte (8 bit) from a specific I/O address:
@code
uint8_t readb(unsigned long)
@endcode

To read a word (16 bit) from a specific I/O address:
@code
uint16_t readw(unsigned long)
@endcode

To read a long word (32 bit) from a specific I/O address:
@code
uint32_t readl(unsigned long)
@endcode

To write a byte (8 bit) into a specific I/O address:
@code
void writeb(uint8_t val, unsigned long)
@endcode

To write a word (16 bit) into a specific I/O address:
@code
void writew(uint16_t val, unsigned long)
@endcode

To write a long word (32 bit) into a specific I/O address:
@code
void writel(uint32_t val, unsigned long)
@endcode

@subsection string_native_access String native access of various width

The following functions are intended to be used for string based I/O access.

To read a string of bytes (8 bit) from one specific I/O address:
@code
void readsb(const void __iomem *addr, void *mem_buffer, int byte_count);
@endcode

To read a string of words (16 bit) from one specific I/O address:
@code
void readsw(const void __iomem *addr, void *mem_buffer, int word_count);
@endcode

To read a string of long words (32 bit) from one specific I/O address:
@code
void readsl(const void __iomem *addr, void *mem_buffer, int long_count);
@endcode

To write a string of bytes (8 bit) to one specific I/O address:
@code
void writesb(void __iomem *addr, const void *mem_buffer, int byte_count);
@endcode

To write a string of words (16 bit) to one specific I/O address:
@code
void writesw(void __iomem *addr, const void *mem_buffer, int word_count);
@endcode

To write a string of long words (32 bit) to one specific I/O address:
@code
void writesl(void __iomem *addr, const void *mem_buffer, int long_count);
@endcode

@section special_access Special IN/OUT access

TBD

*/