DocBook XML validation corrections

There was a bare ampersand in a <title/>, replaced with &amp;
Quite a few <programlisting/> elements also contained bare ampersands, so
each <programlisting/> earned a child element of <![CDATA[]]>
One <parameter/> element lacked quotations on the value for its
class attribute.  Corrected.
This commit is contained in:
Martin A. Brown 2016-01-25 13:13:54 -08:00
parent ce54627b4c
commit 5e96fa268c
1 changed files with 29 additions and 5 deletions

View File

@ -1,4 +1,4 @@
<? xml version="1.0" encoding="ISO-8859-1" ?>
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
]>
@ -142,13 +142,13 @@ host two PCI Mezzanine cards (CCPMC) - Mezzanine cards that comply with Std CCPM
</sect1>
<sect1>
<title>Copyright & License</title>
<title>Copyright &amp; License</title>
<para>Copyright (c) 2002 Shie Elrich</para>
<para>Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in <xref linkend="gfdl">.
A copy of the license is included in <xref linkend="gfdl"/>.
</para>
</sect1>
</chapter>
@ -195,10 +195,12 @@ kernel is not from the HardHat CD, you should enable cross-compiling in the
<filename>Makefile</filename> by defining a CROSS_COMPILE entry in the following manner:
(a code segment from the main Makefile)</para>
<programlisting>
<![CDATA[
CROSS_COMPILE = /opt/hardhat/devkit/ppc/7xx/bin/ppc_7xx-
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
]]>
</programlisting>
<para>The Linux kernel is modular, and allows you to configure it and choose which <quote>blocks</quote>
should be compiled with the kernel. In order to do this, first <command>cd /usr/src/linux</command>
@ -231,7 +233,7 @@ and perform the following steps:
<listitem><para>Initialize the target by pressing <command>Target|Initialize</command></para></listitem>
<listitem><para>Press <command>File|Load Executable</command>. A dialog box will open,
asking you to choose a file. Please choose your kernel image (vmlinux). Before pressing
<command>Load</command>, don't forget to enter a value in the <parameter class=option>+/- Bias</parameter> field.
<command>Load</command>, don't forget to enter a value in the <parameter class="option">+/- Bias</parameter> field.
<tip><para>The bias field makes it possible to tell ICE to load a certain image in a different
address than what's stated in the ELF binary. We wanted to load the kernel into address
<envar>0x300000</envar>, and since the binary was linked to <envar>0xC0000000</envar>, we entered
@ -267,6 +269,7 @@ is it really booting?</para>
and the oldest way is good here - printing to the screen. Obviously, we couldn't use <function>printk()</function>, so we wrote a short function which pushes characters straight into the serial port. We used the boot process <quote>map</quote> shown in the previous section, and inserted some prints along the way. This helped us to know at what stage we are completing and where we're dying. The following piece of code prints a single character to the serial port, by polling it and waiting for it to be free.
<programlisting>
<![CDATA[
/* tx holding reg empty or tx */
#define LSR_THREMPTY 0x20 /* fifo is empty (in fifo mode ) */
#define THR_REG 0x00 /* Transmit holding reg */
@ -281,6 +284,7 @@ void print_char (char ch) {
*((volatile unsigned char *)(COM1_ADDRESS + THR_REG)) = ch;
}
]]>
</programlisting>
<note><para>There's a better code for printing directly to the serial port, however, it's a bit
@ -298,12 +302,14 @@ which are used to mark a certain machine, architecture or device. We defined our
it CONFIG_TESTMACH), and surrounded our new/modified code with these flags:
<programlisting>
<![CDATA[
....original code....
#ifdef CONFIG_TESTMACH
....modified code....
#else
....original code....
#endif /* CONFIG_TESTMACH */
]]>
</programlisting>
To <quote>activate</quote> our code, we added the new flag to the kernel configuration file - <filename>.config</filename> -
@ -326,6 +332,7 @@ in our case <envar>9600n1</envar>, and did not allow any command line options or
This function determines the console configuration at startup. Here's a small part of it:
<programlisting>
<![CDATA[
memset(, 0, sizeof(struct termios));
memcpy(tty_std_termios.c_cc, INIT_C_CC, NCCS);
tty_std_termios.c_iflag = ICRNL | IGNPAR;
@ -337,6 +344,7 @@ tty_std_termios.c_iflag = ICRNL | IXON;
tty_std_termios.c_oflag = OPOST | ONLCR;
tty_std_termios.c_cflag = B38400 | CS8 | CREAD | HUPCL;
tty_std_termios.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN;
]]>
</programlisting>
The first (naive) thing we tried, was to configure the console the way we wanted.
@ -359,7 +367,7 @@ decided it was a good time to let us know that our serial port wasn't standard.
flow control were not connected. We decided to remark-out the following line, which sets the RTS and DTR
lines high, because we just didn't have them.
<programlisting>serial_out(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);</programlisting>
<programlisting><![CDATA[serial_out(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);]]></programlisting>
<emphasis>Ofcourse, this didn't help us much :-(</emphasis>
The lesson learned here was <emphasis>check, check, check your hardware!</emphasis>. Custom boards might
not be standard, and the porting will go a lot quicker if you know about it.</para>
@ -376,11 +384,13 @@ using the board's local bus frequency, bus clock to system clock ratio etc. This
out what the base baud was in a vxWorks system we had running on the board, and changed it to:
<programlisting>
<![CDATA[
/*
* system clock = 33Mhz, serial clock = system clock / 4
* the following must hold: (divisor * BaudRate) == (System clock / 64)
*/
#define BASE_BAUD (33000000 / 4 / 16)
]]>
</programlisting>
A quick compilation, and a reboot later we had a booting kernel visible through our serial port. Success!
@ -402,6 +412,7 @@ A quick compilation, and a reboot later we had a booting kernel visible through
<para>Once all this was done, we found <function>todc_calibrate_descr()</function>, which again uses the RTC chip. We had to replace that function with our own:
<programlisting>
<![CDATA[
void calibrate_decr() {
int freq, divisor;
freq = bus_freq();
@ -409,6 +420,7 @@ void calibrate_decr() {
tb_ticks_per_jiffy = freq / HZ / divisor;
tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000);
}
]]>
</programlisting></para>
</sect1>
@ -424,6 +436,7 @@ void calibrate_decr() {
<para>We discovered that the CPC700 can be initialized to do automatic byte-swapping, which does little-to-big endian convertion on the fly. As it seems, our board was initialized to do just that. We added a small code segment in <function>setup_arch()</function>, which checks if byte-swapping is enabled, and if so, disables it:
<programlisting>
<![CDATA[
while (cnt<2) {
cpc700_read_local_pci_cfgb(0, );
cpc700_read_local_pci_cfgb(1, );
@ -441,6 +454,7 @@ while (cnt<2) {
}
++cnt;
}
]]>
</programlisting>
A short compilation later, PCI probing was working! We got some beer and partied ;-)</para>
@ -452,6 +466,7 @@ A short compilation later, PCI probing was working! We got some beer and partied
<para>Our board uses an Intel ethernet chip, called i82559er, which has a module called <emphasis>eepro100</emphasis>. After compiling the module and booting, we discovered that the module isn't working, although an ethernet device was found. We guessed that it was an irq problem, and that the devices don't get the IRQs they need. We modified a function called <function>pmppc_map_irq()</function> to map our ethernet devices:
<programlisting>
<![CDATA[
XXXX_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) {
static char pci_irq_table[][4] =
/*
@ -471,11 +486,13 @@ XXXX_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) {
const long min_idsel = 3, max_idsel = 9, irqs_per_slot = 4;
return PCI_IRQ_TABLE_LOOKUP;
}
]]>
</programlisting>
The function maps IRQs according to IDselects, which means in the order on the PCI bus by which the devices are set. This structure is a bit tricky: <emphasis>min_idsel</emphasis> denotes the topleft corner of the array, and <emphasis>max_idsel</emphasis> is the bottomleft corner. <emphasis>irqs_per_slot</emphasis> is the number of IRQs per line. The structure is as follows:
<programlisting>
<![CDATA[
each cell contains (IDSEL, SLOT#, IRQ)
+----------------------------------------+
| (3,0,22) | (3,1,0) | (3,2,0) | (3,3,0) |
@ -487,6 +504,7 @@ each cell contains (IDSEL, SLOT#, IRQ)
+----------------------------------------+
| (9,0,0) | (9,1,0) | (9,2,0) | (9,3,0) |
+----------------------------------------+
]]>
</programlisting>
As you can see, our i8559er needs IRQ 22, and is seated in IDselect 3. Of course, we didn't know that at the start, so we wrote a small piece of code that read all the vendor IDs in all the IDselects. Once done we compiled, but the ethernet device still didn't work.</para>
@ -506,11 +524,13 @@ As you can see, our i8559er needs IRQ 22, and is seated in IDselect 3. Of course
<para>As mentioned, there is another way of mapping memory - <function>ioremap()</function>. <function>ioremap()</function> is used to map physical addresses into virtual ones, making them available to the kernel. The function <emphasis>does not allocate any memory</emphasis>, simply returns a virtual address by which one can access the memory region. The following is a snippet from <function>MMU_init()</function>:
<programlisting>
<![CDATA[
case _MACH_mymachine:
setbat(0, LOW_IO_VIRT_BASE, LOW_IO_PHYS_BASE, LOW_IO_SIZE, IO_PAGE);
ioremap(UNIVERSE_BASE,UNIVERSE_SIZE); /* Universe VME */
ioremap(EEPRO100_BASE,EEPRO100_SIZE); /* Ethernet EEPRO100 */
break;
]]>
</programlisting>
As you can see, we don't take the return value of <function>ioremap()</function>. We don't need it, since at this stage the kernel maps the addresses so that virtual address == physical address.</para>
@ -530,6 +550,7 @@ As you can see, we don't take the return value of <function>ioremap()</function
<para>After messing with cache lines, we decided to go the FP way, and added the following function:
<programlisting>
<![CDATA[
void out64(__u32 addr, long long *pVal) {
__u32 flags, tmp_msr;
@ -544,11 +565,13 @@ void out64(__u32 addr, long long *pVal) {
__put_MSR(flags & ~(MSR_EE));
restore_flags(flags);
}
]]>
</programlisting>
The function adds a floating point to the PowerPC MSR register, and makes sure that no exceptions will be generated as a result of doing FP. Once done, it uses an assembly code, described below in the <function>sysOut64()</function> to do the actual floating-point operation. Note that the function turns off interrupts, but this is acceptable here, since we use the function on rare occasion.
<programlisting>
<![CDATA[
_GLOBAL(sysOut64)
stwu r1, -DEPTH(r1)
mflr r0
@ -568,6 +591,7 @@ mtlr r0
lwz r31, -4(r4)
mr r1, r4
blr
]]>
</programlisting></para>
</sect1>