Save 3MB ioport table memory
PATCH 1/1 Save 3MB ioport table memory
Hello,
On 64bit machines, qemu uses 3MB of memory for the ioport tables, while the actual use of them is quite sparse. The patch below saves that memory by leaving them zeroed and just test for that and use the default pointer.
Samuel
vl.c +40 -20
@@ -279,17 +279,29 @@static uint32_t default_ioport_readw (void *opaque,uint32_t address) {uint32_t data; - data = ioport_read_table[0 ][address](ioport_opaque[address], address); +IOPortReadFunc *func = ioport_read_table[0 ][address]; +if (!func) + func = default_ioport_readb; + data =func (ioport_opaque[address], address); address = (address +1 ) & (MAX_IOPORTS -1 ); - data |= ioport_read_table[0 ][address](ioport_opaque[address], address) <<8 ; + func = ioport_read_table[0 ][address]; +if (!func) + func = default_ioport_readb; + data |=func (ioport_opaque[address], address) <<8 ;return data; }static void default_ioport_writew (void *opaque,uint32_t address,uint32_t data) { - ioport_write_table[0 ][address](ioport_opaque[address], address, data &0xff ); +IOPortWriteFunc *func = ioport_write_table[0 ][address]; +if (!func) + func = default_ioport_writeb; +func (ioport_opaque[address], address, data &0xff ); address = (address +1 ) & (MAX_IOPORTS -1 ); - ioport_write_table[0 ][address](ioport_opaque[address], address, (data >>8 ) &0xff ); + func = ioport_write_table[0 ][address]; +if (!func) + func = default_ioport_writeb; +func (ioport_opaque[address], address, (data >>8 ) &0xff ); }static uint32_t default_ioport_readl (void *opaque,uint32_t address)
@@ -309,16 +321,6 @@static void init_ioports (void ) { -int i; - -for (i =0 ; i <MAX_IOPORTS ; i++) { - ioport_read_table[0 ][i] = default_ioport_readb; - ioport_write_table[0 ][i] = default_ioport_writeb; - ioport_read_table[1 ][i] = default_ioport_readw; - ioport_write_table[1 ][i] = default_ioport_writew; - ioport_read_table[2 ][i] = default_ioport_readl; - ioport_write_table[2 ][i] = default_ioport_writel; - } }/* size is the word size in byte */
@@ -390,11 +392,14 @@void cpu_outb (CPUState *env,int addr,int val) { +IOPortWriteFunc *func = ioport_write_table[0 ][addr]; +if (!func) + func = default_ioport_writeb;#ifdef DEBUG_IOPORT if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"outb: %04x %02x\n" , addr, val);#endif - ioport_write_table[0 ][addr](ioport_opaque[addr], addr, val); +func (ioport_opaque[addr], addr, val);#ifdef USE_KQEMU if (env) env->last_io_time =cpu_get_time_fast ();
@@ -403,11 +408,14 @@void cpu_outw (CPUState *env,int addr,int val) { +IOPortWriteFunc *func = ioport_write_table[1 ][addr]; +if (!func) + func = default_ioport_writew;#ifdef DEBUG_IOPORT if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"outw: %04x %04x\n" , addr, val);#endif - ioport_write_table[1 ][addr](ioport_opaque[addr], addr, val); +func (ioport_opaque[addr], addr, val);#ifdef USE_KQEMU if (env) env->last_io_time =cpu_get_time_fast ();
@@ -416,11 +424,14 @@void cpu_outl (CPUState *env,int addr,int val) { +IOPortWriteFunc *func = ioport_write_table[2 ][addr]; +if (!func) + func = default_ioport_writel;#ifdef DEBUG_IOPORT if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"outl: %04x %08x\n" , addr, val);#endif - ioport_write_table[2 ][addr](ioport_opaque[addr], addr, val); +func (ioport_opaque[addr], addr, val);#ifdef USE_KQEMU if (env) env->last_io_time =cpu_get_time_fast ();
@@ -430,7 +441,10 @@int cpu_inb (CPUState *env,int addr) {int val; - val = ioport_read_table[0 ][addr](ioport_opaque[addr], addr); +IOPortReadFunc *func = ioport_read_table[0 ][addr]; +if (!func) + func = default_ioport_readb; + val =func (ioport_opaque[addr], addr);#ifdef DEBUG_IOPORT if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"inb : %04x %02x\n" , addr, val);
@@ -445,7 +459,10 @@int cpu_inw (CPUState *env,int addr) {int val; - val = ioport_read_table[1 ][addr](ioport_opaque[addr], addr); +IOPortReadFunc *func = ioport_read_table[1 ][addr]; +if (!func) + func = default_ioport_readw; + val =func (ioport_opaque[addr], addr);#ifdef DEBUG_IOPORT if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"inw : %04x %04x\n" , addr, val);
@@ -460,7 +477,10 @@int cpu_inl (CPUState *env,int addr) {int val; - val = ioport_read_table[2 ][addr](ioport_opaque[addr], addr); +IOPortReadFunc *func = ioport_read_table[2 ][addr]; +if (!func) + func = default_ioport_readl; + val =func (ioport_opaque[addr], addr);#ifdef DEBUG_IOPORT if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"inl : %04x %08x\n" , addr, val);
Quoted 7 lines · Samuel Thibault
Hello,
On 64bit machines, qemu uses 3MB of memory for the ioport tables, while the actual use of them is quite sparse. The patch below saves that memory by leaving them zeroed and just test for that and use the default pointer.
I really like the idea of this patch. You have some whitespace damage (tabs instead of 8 spaces) and it needs a Signed-off-by: if you'd like me to apply it.
Quoted 7 lines
Samuel
Index:
vl.c
===================================================================
vl.c line 285
Quoted 8 lines
vl.c +3
-1@@ -279,17 +279,29 @@static uint32_t default_ioport_readw (void *opaque,uint32_t address) {uint32_t data; - data = ioport_read_table[0 ][address](ioport_opaque[address], address); +IOPortReadFunc *func = ioport_read_table[0 ][address]; +if (!func) + func = default_ioport_readb;
Perhaps you can introduce an accessor? Something like:
static uint32_t ioport_read_defaults(void *opaque, int index, uint32_t address) {
static IOPortReadFunc *default_funcs[3] = {default_ioport_readb,default_ioport_readw, default_ioport_readl};
IOPortReadFunc *func = ioport_read_table[index][address];
if (!func)
func = default_funcs[index];
return func(opaque, address);
}
That would simplify the rest of the changes significantly.
Regards,
Anthony Liguori
Quoted 1 line · Anthony Liguori, le Tue 22 Jul 2008 20:52:27 -0500, a écrit :
You have some whitespace damage (tabs instead of 8 spaces)
I need to configure vim to autodetect the tab style according to the already existing content :)
Quoted 3 lines
Perhaps you can introduce an accessor?
That would simplify the rest of the changes significantly.
It does indeed.
Save 1.5MB (32bit) or 3MB (64bit) memory by keeping ioport tables sparse and use a test against NULL instead.
vl.c +39 -20
@@ -260,6 +260,35 @@target_phys_addr_t isa_mem_base =0 ;PicState2 *isa_pic; +static IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl; +static IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel; + +static uint32_t default_ioport_readi (int index,uint32_t address) +{ +static IOPortReadFunc *default_func[3 ] = { + default_ioport_readb, + default_ioport_readw, + default_ioport_readl + }; +IOPortReadFunc *func = ioport_read_table[index][address]; +if (!func) + func = default_func[index]; +return func (ioport_opaque[address], address); +} + +static void default_ioport_writei (int index,uint32_t address,uint32_t data) +{ +static IOPortWriteFunc *default_func[3 ] = { + default_ioport_writeb, + default_ioport_writew, + default_ioport_writel + }; +IOPortWriteFunc *func = ioport_write_table[index][address]; +if (!func) + func = default_func[index]; +func (ioport_opaque[address], address, data); +} +static uint32_t default_ioport_readb (void *opaque,uint32_t address) {#ifdef DEBUG_UNUSED_IOPORT
@@ -279,17 +308,17 @@static uint32_t default_ioport_readw (void *opaque,uint32_t address) {uint32_t data; - data = ioport_read_table[0 ][address](ioport_opaque[address], address); + data =default_ioport_readi (0 , address); address = (address +1 ) & (MAX_IOPORTS -1 ); - data |= ioport_read_table[0 ][address](ioport_opaque[address], address) <<8 ; + data |=default_ioport_readi (0 , address) <<8 ;return data; }static void default_ioport_writew (void *opaque,uint32_t address,uint32_t data) { - ioport_write_table[0 ][address](ioport_opaque[address], address, data &0xff ); +default_ioport_writei (0 , address, data &0xff ); address = (address +1 ) & (MAX_IOPORTS -1 ); - ioport_write_table[0 ][address](ioport_opaque[address], address, (data >>8 ) &0xff ); +default_ioport_writei (0 , address, (data >>8 ) &0xff ); }static uint32_t default_ioport_readl (void *opaque,uint32_t address)
@@ -309,16 +338,6 @@static void init_ioports (void ) { -int i; - -for (i =0 ; i <MAX_IOPORTS ; i++) { - ioport_read_table[0 ][i] = default_ioport_readb; - ioport_write_table[0 ][i] = default_ioport_writeb; - ioport_read_table[1 ][i] = default_ioport_readw; - ioport_write_table[1 ][i] = default_ioport_writew; - ioport_read_table[2 ][i] = default_ioport_readl; - ioport_write_table[2 ][i] = default_ioport_writel; - } }/* size is the word size in byte */
@@ -394,7 +413,7 @@if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"outb: %04x %02x\n" , addr, val);#endif - ioport_write_table[0 ][addr](ioport_opaque[addr], addr, val); +default_ioport_writei (0 , addr, val);#ifdef USE_KQEMU if (env) env->last_io_time =cpu_get_time_fast ();
@@ -407,7 +426,7 @@if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"outw: %04x %04x\n" , addr, val);#endif - ioport_write_table[1 ][addr](ioport_opaque[addr], addr, val); +default_ioport_writei (1 , addr, val);#ifdef USE_KQEMU if (env) env->last_io_time =cpu_get_time_fast ();
@@ -420,7 +439,7 @@if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"outl: %04x %08x\n" , addr, val);#endif - ioport_write_table[2 ][addr](ioport_opaque[addr], addr, val); +default_ioport_writei (2 , addr, val);#ifdef USE_KQEMU if (env) env->last_io_time =cpu_get_time_fast ();
@@ -430,7 +449,7 @@int cpu_inb (CPUState *env,int addr) {int val; - val = ioport_read_table[0 ][addr](ioport_opaque[addr], addr); + val =default_ioport_readi (0 , addr);#ifdef DEBUG_IOPORT if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"inb : %04x %02x\n" , addr, val);
@@ -445,7 +464,7 @@int cpu_inw (CPUState *env,int addr) {int val; - val = ioport_read_table[1 ][addr](ioport_opaque[addr], addr); + val =default_ioport_readi (1 , addr);#ifdef DEBUG_IOPORT if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"inw : %04x %04x\n" , addr, val);
@@ -460,7 +479,7 @@int cpu_inl (CPUState *env,int addr) {int val; - val = ioport_read_table[2 ][addr](ioport_opaque[addr], addr); + val =default_ioport_readi (2 , addr);#ifdef DEBUG_IOPORT if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"inl : %04x %08x\n" , addr, val);
Quoted 6 lines · Samuel Thibault
static void
init_ioports(void)
{
- int i;
...
- }
}
Why are you leaving empty functions?
Quoted 1 line
+static
uint32_tdefault_ioport_readi(int index, uint32_t address)
While the abstraction is good, I don't like the name of this function. I'd expect this to be a direct wrapper round default_ioport_read[bwl], not something that calls the actual IO port handler. If your patch contains no comments then everything must be intuitive and self-explanatory. Currently it it not.
Paul
Quoted 1 line · Paul Brook, le Wed 23 Jul 2008 13:15:42 +0100, a écrit :
Why are you leaving empty functions?
In case somebody wants to fill it again? :)
Quoted 5 lines
Quoted 1 line
+static
uint32_tdefault_ioport_readi(int index, uint32_t address)While the abstraction is good, I don't like the name of this function. I'd expect this to be a direct wrapper round default_ioport_read[bwl], not something that calls the actual IO port handler.
Ah, right, here is an updated patch.
Samuel
Save 1.5MB (32bit) or 3MB (64bit) memory by keeping ioport tables sparse and use a test against NULL instead.
vl.c +39 -26
@@ -260,6 +260,35 @@target_phys_addr_t isa_mem_base =0 ;PicState2 *isa_pic; +static IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl; +static IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel; + +static uint32_t ioport_read (int index,uint32_t address) +{ +static IOPortReadFunc *default_func[3 ] = { + default_ioport_readb, + default_ioport_readw, + default_ioport_readl + }; +IOPortReadFunc *func = ioport_read_table[index][address]; +if (!func) + func = default_func[index]; +return func (ioport_opaque[address], address); +} + +static void ioport_write (int index,uint32_t address,uint32_t data) +{ +static IOPortWriteFunc *default_func[3 ] = { + default_ioport_writeb, + default_ioport_writew, + default_ioport_writel + }; +IOPortWriteFunc *func = ioport_write_table[index][address]; +if (!func) + func = default_func[index]; +func (ioport_opaque[address], address, data); +} +static uint32_t default_ioport_readb (void *opaque,uint32_t address) {#ifdef DEBUG_UNUSED_IOPORT
@@ -279,17 +308,17 @@static uint32_t default_ioport_readw (void *opaque,uint32_t address) {uint32_t data; - data = ioport_read_table[0 ][address](ioport_opaque[address], address); + data =ioport_read (0 , address); address = (address +1 ) & (MAX_IOPORTS -1 ); - data |= ioport_read_table[0 ][address](ioport_opaque[address], address) <<8 ; + data |=ioport_read (0 , address) <<8 ;return data; }static void default_ioport_writew (void *opaque,uint32_t address,uint32_t data) { - ioport_write_table[0 ][address](ioport_opaque[address], address, data &0xff ); +ioport_write (0 , address, data &0xff ); address = (address +1 ) & (MAX_IOPORTS -1 ); - ioport_write_table[0 ][address](ioport_opaque[address], address, (data >>8 ) &0xff ); +ioport_write (0 , address, (data >>8 ) &0xff ); }static uint32_t default_ioport_readl (void *opaque,uint32_t address)
@@ -307,20 +336,6 @@#endif } -static void init_ioports (void ) -{ -int i; - -for (i =0 ; i <MAX_IOPORTS ; i++) { - ioport_read_table[0 ][i] = default_ioport_readb; - ioport_write_table[0 ][i] = default_ioport_writeb; - ioport_read_table[1 ][i] = default_ioport_readw; - ioport_write_table[1 ][i] = default_ioport_writew; - ioport_read_table[2 ][i] = default_ioport_readl; - ioport_write_table[2 ][i] = default_ioport_writel; - } -} -/* size is the word size in byte */ int register_ioport_read (int start,int length,int size,IOPortReadFunc *func,void *opaque)
@@ -394,7 +409,7 @@if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"outb: %04x %02x\n" , addr, val);#endif - ioport_write_table[0 ][addr](ioport_opaque[addr], addr, val); +ioport_write (0 , addr, val);#ifdef USE_KQEMU if (env) env->last_io_time =cpu_get_time_fast ();
@@ -407,7 +422,7 @@if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"outw: %04x %04x\n" , addr, val);#endif - ioport_write_table[1 ][addr](ioport_opaque[addr], addr, val); +ioport_write (1 , addr, val);#ifdef USE_KQEMU if (env) env->last_io_time =cpu_get_time_fast ();
@@ -420,7 +435,7 @@if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"outl: %04x %08x\n" , addr, val);#endif - ioport_write_table[2 ][addr](ioport_opaque[addr], addr, val); +ioport_write (2 , addr, val);#ifdef USE_KQEMU if (env) env->last_io_time =cpu_get_time_fast ();
@@ -430,7 +445,7 @@int cpu_inb (CPUState *env,int addr) {int val; - val = ioport_read_table[0 ][addr](ioport_opaque[addr], addr); + val =ioport_read (0 , addr);#ifdef DEBUG_IOPORT if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"inb : %04x %02x\n" , addr, val);
@@ -445,7 +460,7 @@int cpu_inw (CPUState *env,int addr) {int val; - val = ioport_read_table[1 ][addr](ioport_opaque[addr], addr); + val =ioport_read (1 , addr);#ifdef DEBUG_IOPORT if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"inw : %04x %04x\n" , addr, val);
@@ -460,7 +475,7 @@int cpu_inl (CPUState *env,int addr) {int val; - val = ioport_read_table[2 ][addr](ioport_opaque[addr], addr); + val =ioport_read (2 , addr);#ifdef DEBUG_IOPORT if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"inl : %04x %08x\n" , addr, val);
@@ -8832,8 +8847,6 @@register_savevm ("timer" ,0 ,2 , timer_save, timer_load,NULL );register_savevm ("ram" ,0 ,2 , ram_save, ram_load,NULL ); -init_ioports (); -/* terminal init */ memset (&display_state,0 ,sizeof (display_state));if (nographic) {
Anthony Liguori
AppliedQuoted 5 lines · Samuel Thibault
Save 1.5MB (32bit) or 3MB (64bit) memory by keeping ioport tables sparse and use a test against NULL instead.
Signed-off-by Samuel Thibault <[email protected]>
Applied. Thanks.
In the future, please make your patches apply with -p1 and resubmit patches as a top-level post with an indication of the patch version (v3). It's easy to miss a patch that's deep within a thread.
Regards,
Anthony Liguori
Quoted 147 lines
Index:
vl.c
===================================================================vl.c +39
-26@@ -260,6 +260,35 @@target_phys_addr_t isa_mem_base =0 ;PicState2 *isa_pic; +static IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl; +static IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel; + +static uint32_t ioport_read (int index,uint32_t address) +{ +static IOPortReadFunc *default_func[3 ] = { + default_ioport_readb, + default_ioport_readw, + default_ioport_readl + }; +IOPortReadFunc *func = ioport_read_table[index][address]; +if (!func) + func = default_func[index]; +return func (ioport_opaque[address], address); +} + +static void ioport_write (int index,uint32_t address,uint32_t data) +{ +static IOPortWriteFunc *default_func[3 ] = { + default_ioport_writeb, + default_ioport_writew, + default_ioport_writel + }; +IOPortWriteFunc *func = ioport_write_table[index][address]; +if (!func) + func = default_func[index]; +func (ioport_opaque[address], address, data); +} +static uint32_t default_ioport_readb (void *opaque,uint32_t address) {#ifdef DEBUG_UNUSED_IOPORT @@ -279,17 +308,17 @@static uint32_t default_ioport_readw (void *opaque,uint32_t address) {uint32_t data; - data = ioport_read_table[0 ][address](ioport_opaque[address], address); + data =ioport_read (0 , address); address = (address +1 ) & (MAX_IOPORTS -1 ); - data |= ioport_read_table[0 ][address](ioport_opaque[address], address) <<8 ; + data |=ioport_read (0 , address) <<8 ;return data; }static void default_ioport_writew (void *opaque,uint32_t address,uint32_t data) { - ioport_write_table[0 ][address](ioport_opaque[address], address, data &0xff ); +ioport_write (0 , address, data &0xff ); address = (address +1 ) & (MAX_IOPORTS -1 ); - ioport_write_table[0 ][address](ioport_opaque[address], address, (data >>8 ) &0xff ); +ioport_write (0 , address, (data >>8 ) &0xff ); }static uint32_t default_ioport_readl (void *opaque,uint32_t address)@@ -307,20 +336,6 @@#endif } -static void init_ioports (void ) -{ -int i; - -for (i =0 ; i <MAX_IOPORTS ; i++) { - ioport_read_table[0 ][i] = default_ioport_readb; - ioport_write_table[0 ][i] = default_ioport_writeb; - ioport_read_table[1 ][i] = default_ioport_readw; - ioport_write_table[1 ][i] = default_ioport_writew; - ioport_read_table[2 ][i] = default_ioport_readl; - ioport_write_table[2 ][i] = default_ioport_writel; - } -} -/* size is the word size in byte */ int register_ioport_read (int start,int length,int size,IOPortReadFunc *func,void *opaque)@@ -394,7 +409,7 @@if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"outb: %04x %02x\n" , addr, val);#endif - ioport_write_table[0 ][addr](ioport_opaque[addr], addr, val); +ioport_write (0 , addr, val);#ifdef USE_KQEMU if (env) env->last_io_time =cpu_get_time_fast ();@@ -407,7 +422,7 @@if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"outw: %04x %04x\n" , addr, val);#endif - ioport_write_table[1 ][addr](ioport_opaque[addr], addr, val); +ioport_write (1 , addr, val);#ifdef USE_KQEMU if (env) env->last_io_time =cpu_get_time_fast ();@@ -420,7 +435,7 @@if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"outl: %04x %08x\n" , addr, val);#endif - ioport_write_table[2 ][addr](ioport_opaque[addr], addr, val); +ioport_write (2 , addr, val);#ifdef USE_KQEMU if (env) env->last_io_time =cpu_get_time_fast ();@@ -430,7 +445,7 @@int cpu_inb (CPUState *env,int addr) {int val; - val = ioport_read_table[0 ][addr](ioport_opaque[addr], addr); + val =ioport_read (0 , addr);#ifdef DEBUG_IOPORT if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"inb : %04x %02x\n" , addr, val);@@ -445,7 +460,7 @@int cpu_inw (CPUState *env,int addr) {int val; - val = ioport_read_table[1 ][addr](ioport_opaque[addr], addr); + val =ioport_read (1 , addr);#ifdef DEBUG_IOPORT if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"inw : %04x %04x\n" , addr, val);@@ -460,7 +475,7 @@int cpu_inl (CPUState *env,int addr) {int val; - val = ioport_read_table[2 ][addr](ioport_opaque[addr], addr); + val =ioport_read (2 , addr);#ifdef DEBUG_IOPORT if (loglevel &CPU_LOG_IOPORT )fprintf (logfile,"inl : %04x %08x\n" , addr, val);@@ -8832,8 +8847,6 @@register_savevm ("timer" ,0 ,2 , timer_save, timer_load,NULL );register_savevm ("ram" ,0 ,2 , ram_save, ram_load,NULL ); -init_ioports (); -/* terminal init */ memset (&display_state,0 ,sizeof (display_state));if (nographic) {
Quoted 3 lines
In the future, please make your patches apply with -p1 and resubmit patches as a top-level post with an indication of the patch version (v3). It's easy to miss a patch that's deep within a thread.
Patches that apply with -p0 are also fine - this is what svn generates.
Paul
Quoted 7 lines · Paul Brook
Quoted 4 lines
In the future, please make your patches apply with -p1 and resubmit patches as a top-level post with an indication of the patch version (v3). It's easy to miss a patch that's deep within a thread.
Patches that apply with -p0 are also fine - this is what svn generates.
Oh, sorry. I'm new to svn.
Regards,
Anthony Liguori
Quoted 2 lines
Paul