| /** @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_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 |
| |
| */ |