diff options
-rw-r--r-- | src/northbridge/intel/x4x/Makefile.inc | 1 | ||||
-rw-r--r-- | src/northbridge/intel/x4x/raminit_ddr2.c | 168 | ||||
-rw-r--r-- | src/northbridge/intel/x4x/raminit_tables.c | 271 | ||||
-rw-r--r-- | src/northbridge/intel/x4x/x4x.h | 44 |
4 files changed, 390 insertions, 94 deletions
diff --git a/src/northbridge/intel/x4x/Makefile.inc b/src/northbridge/intel/x4x/Makefile.inc index 5c64ca7e49..fb9dc1591b 100644 --- a/src/northbridge/intel/x4x/Makefile.inc +++ b/src/northbridge/intel/x4x/Makefile.inc @@ -21,6 +21,7 @@ romstage-y += raminit.c romstage-y += raminit_ddr2.c romstage-y += ram_calc.c romstage-y += rcven.c +romstage-y += raminit_tables.c ramstage-y += acpi.c ramstage-y += ram_calc.c diff --git a/src/northbridge/intel/x4x/raminit_ddr2.c b/src/northbridge/intel/x4x/raminit_ddr2.c index 336f77ec7d..866815f729 100644 --- a/src/northbridge/intel/x4x/raminit_ddr2.c +++ b/src/northbridge/intel/x4x/raminit_ddr2.c @@ -26,6 +26,7 @@ #else #include <southbridge/intel/i82801jx/i82801jx.h> #endif +#include <string.h> #include "iomap.h" #include "x4x.h" @@ -344,6 +345,24 @@ static void dqset(u8 ch, u8 lane, const struct dll_setting *setting) } } +static void rt_set_dqs(u8 channel, u8 lane, u8 rank, + struct rt_dqs_setting *dqs_setting) +{ + u16 saved_tap = MCHBAR16(0x540 + 0x400 * channel + lane * 4); + u16 saved_pi = MCHBAR16(0x542 + 0x400 * channel + lane * 4); + printk(RAM_SPEW, "RT DQS: ch%d, L%d, %d.%d\n", channel, lane, + dqs_setting->tap, + dqs_setting->pi); + + saved_tap &= ~(0xf << (rank * 4)); + saved_tap |= dqs_setting->tap << (rank * 4); + MCHBAR16(0x540 + 0x400 * channel + lane * 4) = saved_tap; + + saved_pi &= ~(0x7 << (rank * 3)); + saved_pi |= dqs_setting->pi << (rank * 3); + MCHBAR16(0x542 + 0x400 * channel + lane * 4) = saved_pi; +} + static void timings_ddr2(struct sysinfo *s) { u8 i; @@ -574,7 +593,6 @@ static void dll_ddr2(struct sysinfo *s) u8 i, j, r, reg8, clk, async = 0; u16 reg16 = 0; u32 reg32 = 0; - u8 lane; MCHBAR16(0x180) = (MCHBAR16(0x180) & ~0x7e06) | 0xc04; MCHBAR16(0x182) = (MCHBAR16(0x182) & ~0x3ff) | 0xc8; @@ -660,60 +678,6 @@ static void dll_ddr2(struct sysinfo *s) MCHBAR8(0x1a4) = MCHBAR8(0x1a4) | 0x40; MCHBAR16(0x5f0) = (MCHBAR16(0x5f0) & ~0x400) | 0x400; - static const struct dll_setting dll_setting_667[23] = { - // tap pi db delay - {13, 0, 1, 0, 0}, - {4, 1, 0, 0, 0}, - {13, 0, 1, 0, 0}, - {4, 5, 0, 0, 0}, - {4, 1, 0, 0, 0}, - {4, 1, 0, 0, 0}, - {4, 1, 0, 0, 0}, - {1, 5, 1, 1, 1}, - {1, 6, 1, 1, 1}, - {2, 0, 1, 1, 1}, - {2, 1, 1, 1, 1}, - {2, 1, 1, 1, 1}, - {14, 6, 1, 0, 0}, - {14, 3, 1, 0, 0}, - {14, 0, 1, 0, 0}, - {9, 0, 0, 0, 1}, - {9, 1, 0, 0, 1}, - {9, 2, 0, 0, 1}, - {9, 2, 0, 0, 1}, - {9, 1, 0, 0, 1}, - {6, 4, 0, 0, 1}, - {6, 2, 0, 0, 1}, - {5, 4, 0, 0, 1} - }; - - static const struct dll_setting dll_setting_800[23] = { - // tap pi db delay - {11, 5, 1, 0, 0}, - {0, 5, 1, 1, 0}, - {11, 5, 1, 0, 0}, - {1, 4, 1, 1, 0}, - {0, 5, 1, 1, 0}, - {0, 5, 1, 1, 0}, - {0, 5, 1, 1, 0}, - {2, 5, 1, 1, 1}, - {2, 6, 1, 1, 1}, - {3, 0, 1, 1, 1}, - {3, 0, 1, 1, 1}, - {3, 3, 1, 1, 1}, - {2, 0, 1, 1, 1}, - {1, 3, 1, 1, 1}, - {0, 3, 1, 1, 1}, - {9, 3, 0, 0, 1}, - {9, 4, 0, 0, 1}, - {9, 5, 0, 0, 1}, - {9, 6, 0, 0, 1}, - {10, 0, 0, 0, 1}, - {8, 1, 0, 0, 1}, - {7, 5, 0, 0, 1}, - {6, 2, 0, 0, 1} - }; - FOR_EACH_POPULATED_CHANNEL(s->dimms, i) { MCHBAR16(0x400*i + 0x5f0) = (MCHBAR16(0x400*i + 0x5f0) & ~0x3fc) | 0x3fc; MCHBAR32(0x400*i + 0x5fc) = MCHBAR32(0x400*i + 0x5fc) & ~0xcccccccc; @@ -725,9 +689,9 @@ static void dll_ddr2(struct sysinfo *s) const struct dll_setting *setting; if (s->selected_timings.mem_clk == MEM_CLOCK_667MHz) - setting = dll_setting_667; + setting = default_ddr2_667_ctrl; else - setting = dll_setting_800; + setting = default_ddr2_800_ctrl; clkset0(i, &setting[CLKSET0]); clkset1(i, &setting[CLKSET1]); @@ -834,32 +798,77 @@ static void dll_ddr2(struct sysinfo *s) if (s->selected_timings.mem_clk == MEM_CLOCK_1333MHz) MCHBAR8(0x18c) = MCHBAR8(0x18c) | 1; +} - // Program DQ/DQS dll settings - reg32 = 0; - FOR_EACH_POPULATED_CHANNEL(s->dimms, i) { +static void select_default_dq_dqs_settings(struct sysinfo *s) +{ + int ch, lane; + + FOR_EACH_POPULATED_CHANNEL(s->dimms, ch) { for (lane = 0; lane < 8; lane++) { - if (s->selected_timings.mem_clk == MEM_CLOCK_667MHz) - reg32 = 0x06db7777; - else if (s->selected_timings.mem_clk == MEM_CLOCK_800MHz) - reg32 = 0x00007777; - MCHBAR32(0x400*i + 0x540 + lane*4) = - (MCHBAR32(0x400*i + 0x540 + lane*4) & 0x0fffffff) | - reg32; + switch (s->selected_timings.mem_clk) { + case MEM_CLOCK_667MHz: + memcpy(s->dqs_settings[ch], + default_ddr2_667_dqs, + sizeof(s->dqs_settings[ch])); + memcpy(s->dq_settings[ch], + default_ddr2_667_dq, + sizeof(s->dq_settings[ch])); + s->rt_dqs[ch][lane].tap = 7; + s->rt_dqs[ch][lane].pi = 2; + break; + case MEM_CLOCK_800MHz: + if (s->spd_type == DDR2) { + memcpy(s->dqs_settings[ch], + default_ddr2_800_dqs, + sizeof(s->dqs_settings[ch])); + memcpy(s->dq_settings[ch], + default_ddr2_800_dq, + sizeof(s->dq_settings[ch])); + + s->rt_dqs[ch][lane].tap = 7; + s->rt_dqs[ch][lane].pi = 0; + } else { /* DDR3 */ + /* TODO: DDR3 write DQ-DQS */ + s->rt_dqs[ch][lane].tap = 6; + s->rt_dqs[ch][lane].pi = 2; + } + break; + case MEM_CLOCK_1066MHz: + /* TODO: DDR3 write DQ-DQS */ + s->rt_dqs[ch][lane].tap = 5; + s->rt_dqs[ch][lane].pi = 2; + break; + case MEM_CLOCK_1333MHz: + /* TODO: DDR3 write DQ-DQS */ + s->rt_dqs[ch][lane].tap = 7; + s->rt_dqs[ch][lane].pi = 0; + break; + default: /* not supported */ + break; + } } } +} - FOR_EACH_POPULATED_CHANNEL(s->dimms, i) { - if (s->selected_timings.mem_clk == MEM_CLOCK_667MHz) { - for (lane = 0; lane < 8; lane++) - dqsset(i, lane, &dll_setting_667[DQS1+lane]); - for (lane = 0; lane < 8; lane++) - dqset(i, lane, &dll_setting_667[DQ1+lane]); - } else { - for (lane = 0; lane < 8; lane++) - dqsset(i, lane, &dll_setting_800[DQS1+lane]); - for (lane = 0; lane < 8; lane++) - dqset(i, lane, &dll_setting_800[DQ1+lane]); +/* + * It looks like only the RT DQS register for the first rank + * is used for all ranks. Just set all the 'unused' RT DQS registers + * to the same as rank 0, out of precaution. + */ +static void set_all_dq_dqs_dll_settings(struct sysinfo *s) +{ + // Program DQ/DQS dll settings + int ch, lane, rank; + + FOR_EACH_POPULATED_CHANNEL(s->dimms, ch) { + for (lane = 0; lane < 8; lane++) { + FOR_EACH_RANK_IN_CHANNEL(rank) { + rt_set_dqs(ch, lane, rank, + &s->rt_dqs[ch][lane]); + } + dqsset(ch, lane, &s->dqs_settings[ch][lane]); + dqset(ch, lane, &s->dq_settings[ch][lane]); } } } @@ -1486,6 +1495,9 @@ void raminit_ddr2(struct sysinfo *s, int fast_boot) // Program DLL dll_ddr2(s); + if (!fast_boot) + select_default_dq_dqs_settings(s); + set_all_dq_dqs_dll_settings(s); // RCOMP if (s->boot_path != BOOT_PATH_WARM_RESET) { diff --git a/src/northbridge/intel/x4x/raminit_tables.c b/src/northbridge/intel/x4x/raminit_tables.c new file mode 100644 index 0000000000..f386b6bc00 --- /dev/null +++ b/src/northbridge/intel/x4x/raminit_tables.c @@ -0,0 +1,271 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Arthur Heymans <arthur@aheymans.xyz> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/io.h> +#include <stdint.h> +#include "x4x.h" + +const struct dll_setting default_ddr2_667_ctrl[7] = { + /* tap pi db delay coarse*/ + {13, 0, 1, 0, 0, 0}, /* clkset0 */ + {4, 1, 0, 0, 0, 0}, /* ctrl0 */ + {13, 0, 1, 0, 0, 0}, /* clkset1 */ + {4, 5, 0, 0, 0, 0}, /* cmd */ + {4, 1, 0, 0, 0, 0}, /* ctrl1 */ + {4, 1, 0, 0, 0, 0}, /* ctrl2 */ + {4, 1, 0, 0, 0, 0}, /* ctrl3 */ +}; + +const struct dll_setting default_ddr2_667_dqs[8] = { + {1, 5, 1, 1, 1, 0}, + {1, 6, 1, 1, 1, 0}, + {2, 0, 1, 1, 1, 0}, + {2, 1, 1, 1, 1, 0}, + {2, 1, 1, 1, 1, 0}, + {14, 6, 1, 0, 0, 0}, + {14, 3, 1, 0, 0, 0}, + {14, 0, 1, 0, 0, 0}, +}; + +const struct dll_setting default_ddr2_667_dq[8] = { + {9, 0, 0, 0, 1, 0}, + {9, 1, 0, 0, 1, 0}, + {9, 2, 0, 0, 1, 0}, + {9, 2, 0, 0, 1, 0}, + {9, 1, 0, 0, 1, 0}, + {6, 4, 0, 0, 1, 0}, + {6, 2, 0, 0, 1, 0}, + {5, 4, 0, 0, 1, 0} +}; + +const struct dll_setting default_ddr2_800_ctrl[7] = { + /* tap pi db delay coarse */ + {11, 5, 1, 0, 0, 0}, + {0, 5, 1, 1, 0, 0}, + {11, 5, 1, 0, 0, 0}, + {1, 4, 1, 1, 0, 0}, + {0, 5, 1, 1, 0, 0}, + {0, 5, 1, 1, 0, 0}, + {0, 5, 1, 1, 0, 0}, +}; + +const struct dll_setting default_ddr2_800_dqs[8] = { + {2, 5, 1, 1, 1, 0}, + {2, 6, 1, 1, 1, 0}, + {3, 0, 1, 1, 1, 0}, + {3, 0, 1, 1, 1, 0}, + {3, 3, 1, 1, 1, 0}, + {2, 0, 1, 1, 1, 0}, + {1, 3, 1, 1, 1, 0}, + {0, 3, 1, 1, 1, 0}, +}; + +const struct dll_setting default_ddr2_800_dq[8] = { + {9, 3, 0, 0, 1, 0}, + {9, 4, 0, 0, 1, 0}, + {9, 5, 0, 0, 1, 0}, + {9, 6, 0, 0, 1, 0}, + {10, 0, 0, 0, 1, 0}, + {8, 1, 0, 0, 1, 0}, + {7, 5, 0, 0, 1, 0}, + {6, 2, 0, 0, 1, 0} +}; + +const struct dll_setting default_ddr3_800_ctrl[2][7] = { + { /* 1N */ + /* tap pi db(2) delay coarse */ + {8, 2, 0, 0, 0, 0}, + {8, 4, 0, 0, 0, 0}, + {9, 5, 0, 0, 0, 0}, + {6, 1, 0, 0, 0, 0}, + {8, 4, 0, 0, 0, 0}, + {10, 0, 0, 0, 0, 0}, + {10, 0, 0, 0, 0, 0}, }, + { /* 2N */ + {2, 2, 1, 1, 0, 0}, + {2, 4, 1, 1, 0, 0}, + {3, 5, 0, 0, 0, 0}, + {3, 2, 1, 1, 0, 0}, + {2, 4, 1, 1, 0, 0}, + {3, 6, 0, 0, 0, 0}, + {3, 6, 0, 0, 0, 0}, } +}; + +const struct dll_setting default_ddr3_800_dqs[2][8] = { + { /* 1N */ + {12, 0, 1, 0, 0, 0}, + {1, 1, 1, 1, 1, 0}, + {2, 4, 1, 1, 1, 0}, + {3, 5, 0, 0, 1, 0}, + {4, 3, 0, 0, 1, 0}, + {5, 2, 0, 0, 1, 0}, + {6, 1, 0, 0, 1, 0}, + {6, 4, 0, 0, 1, 0}, }, + { /* 2N */ + {5, 6, 0, 0, 0, 0}, + {8, 0, 0, 0, 0, 0}, + {9, 4, 0, 0, 0, 0}, + {10, 4, 1, 0, 0, 0}, + {11, 3, 1, 0, 0, 0}, + {12, 1, 1, 0, 0, 0}, + {0, 1, 1, 1, 1, 0}, + {0, 3, 1, 1, 1, 0}, } +}; + +const struct dll_setting default_ddr3_800_dq[2][8] = { + { /* 1N */ + {4, 1, 0, 0, 1, 0}, + {6, 4, 0, 0, 1, 0}, + {8, 1, 0, 0, 1, 0}, + {8, 6, 0, 0, 1, 0}, + {9, 5, 0, 0, 1, 0}, + {10, 2, 0, 0, 1, 0}, + {10, 6, 1, 0, 1, 0}, + {11, 4, 1, 0, 1, 0} }, + { /* 2N */ + {11, 0, 1, 0, 0, 0}, + {0, 3, 1, 1, 1, 0}, + {2, 1, 1, 1, 1, 0}, + {2, 5, 1, 1, 1, 0}, + {3, 5, 0, 0, 1, 0}, + {4, 2, 0, 0, 1, 0}, + {4, 6, 0, 0, 1, 0}, + {5, 4, 0, 0, 1, 0}, } +}; + +const struct dll_setting default_ddr3_1067_ctrl[2][7] = { + { /* 1N */ + {8, 5, 0, 0, 0, 0}, + {7, 6, 0, 0, 0, 0}, + {10, 2, 1, 0, 0, 0}, + {4, 4, 0, 0, 0, 0}, + {7, 6, 0, 0, 0, 0}, + {9, 2, 1, 0, 0, 0}, + {9, 2, 1, 0, 0, 0}, }, + { /* 2N */ + {1, 5, 1, 1, 0, 0}, + {0, 6, 1, 1, 0, 0}, + {3, 2, 0, 0, 0, 0}, + {2, 6, 1, 1, 0, 0}, + {0, 6, 1, 1, 0, 0}, + {2, 2, 1, 1, 0, 0}, + {2, 2, 1, 1, 0, 0}, } +}; + +const struct dll_setting default_ddr3_1067_dqs[2][8] = { + { /* 1N */ + {2, 5, 1, 1, 1, 0}, + {5, 1, 0, 0, 1, 0}, + {6, 6, 0, 0, 1, 0}, + {8, 0, 0, 0, 1, 0}, + {8, 6, 0, 0, 1, 0}, + {9, 6, 1, 0, 1, 0}, + {10, 6, 1, 0, 1, 0}, + {0, 1, 1, 1, 0, 1}, }, + { /* 2N */ + {6, 4, 0, 0, 0, 0}, + {9, 1, 1, 0, 0, 0}, + {10, 6, 1, 0, 0, 0}, + {1, 0, 1, 1, 1, 0}, + {1, 6, 1, 1, 1, 0}, + {2, 5, 1, 1, 1, 0}, + {3, 5, 0, 0, 1, 0}, + {4, 1, 0, 0, 1, 0}, + } +}; + +const struct dll_setting default_ddr3_1067_dq[2][8] = { + { /* 1N */ + {6, 5, 0, 0, 1, 0}, + {9, 3, 1, 0, 1, 0}, + {0, 2, 1, 1, 0, 1}, + {1, 0, 1, 1, 0, 1}, + {2, 0, 1, 1, 0, 1}, + {2, 5, 1, 1, 0, 1}, + {3, 2, 0, 0, 0, 1}, + {4, 1, 0, 0, 0, 1}, }, + { /* 2N */ + {10, 5, 1, 0, 0, 0}, + {2, 3, 1, 1, 1, 0}, + {4, 1, 0, 0, 1, 0}, + {5, 0, 0, 0, 1, 0}, + {6, 0, 0, 0, 1, 0}, + {6, 5, 0, 0, 1, 0}, + {7, 2, 0, 0, 1, 0}, + {8, 1, 0, 0, 1, 0}, + } +}; + +const struct dll_setting default_ddr3_1333_ctrl[2][7] = { + { /* 1N */ + {8, 5, 0, 0, 0, 0}, + {9, 0, 1, 0, 0, 0}, + {10, 2, 1, 0, 0, 0}, + {0, 0, 1, 1, 0, 0}, + {9, 0, 1, 0, 0, 0}, + {10, 4, 1, 0, 0, 0}, + {10, 4, 1, 0, 0, 0}, }, + { /* 2N */ + {1, 6, 1, 1, 0, 0}, + {2, 2, 1, 1, 0, 0}, + {4, 2, 0, 0, 0, 0}, + {3, 1, 1, 1, 0, 0}, + {2, 2, 1, 1, 0, 0}, + {4, 5, 0, 0, 0, 0}, + {4, 5, 0, 0, 0, 0}, } +}; + +const struct dll_setting default_ddr3_1333_dqs[2][8] = { + { /* 1N */ + {2, 4, 1, 1, 1, 0}, + {5, 1, 0, 0, 1, 0}, + {6, 6, 0, 0, 1, 0}, + {8, 0, 0, 0, 1, 0}, + {8, 6, 0, 0, 1, 0}, + {9, 5, 1, 0, 1, 0}, + {10, 6, 1, 0, 1, 0}, + {0, 1, 1, 1, 0, 1}, }, + { /* 2N */ + {10, 4, 0, 0, 0, 0}, + {0, 3, 1, 1, 1, 0}, + {3, 2, 1, 1, 1, 0}, + {5, 0, 0, 0, 1, 0}, + {6, 1, 0, 0, 1, 0}, + {7, 4, 0, 0, 1, 0}, + {9, 2, 0, 0, 1, 0}, + {9, 6, 0, 0, 1, 0}, } +}; + +const struct dll_setting default_ddr3_1333_dq[2][8] = { + { /* 1N */ + {6, 5, 0, 0, 1, 0}, + {9, 3, 1, 0, 1, 0}, + {0, 2, 1, 1, 0, 1}, + {1, 0, 1, 1, 0, 1}, + {2, 0, 1, 1, 0, 1}, + {2, 5, 1, 1, 0, 1}, + {3, 2, 0, 0, 0, 1}, + {4, 1, 0, 0, 0, 1}, }, + { /* 2N */ + {1, 3, 1, 1, 1, 0}, + {5, 6, 0, 0, 1, 0}, + {8, 5, 0, 0, 1, 0}, + {10, 2, 0, 0, 1, 0}, + {11, 1, 0, 0, 1, 0}, + {12, 3, 1, 0, 1, 0}, + {13, 6, 1, 0, 1, 0}, + {0, 3, 1, 1, 0, 1}, } +}; diff --git a/src/northbridge/intel/x4x/x4x.h b/src/northbridge/intel/x4x/x4x.h index 70c6525bba..146f865647 100644 --- a/src/northbridge/intel/x4x/x4x.h +++ b/src/northbridge/intel/x4x/x4x.h @@ -250,6 +250,11 @@ struct dll_setting { u8 coarse; }; +struct rt_dqs_setting { + u8 tap; + u8 pi; +}; + enum n_banks { N_BANKS_4 = 0, N_BANKS_8 = 1, @@ -303,6 +308,13 @@ struct sysinfo { struct dimminfo dimms[4]; u8 spd_map[4]; struct rcven_timings rcven_t[TOTAL_CHANNELS]; + /* + * The rt_dqs delay register for rank 0 seems to be used + * for all other ranks on the channel, so only save that + */ + struct rt_dqs_setting rt_dqs[TOTAL_CHANNELS][8]; + struct dll_setting dqs_settings[TOTAL_CHANNELS][8]; + struct dll_setting dq_settings[TOTAL_CHANNELS][8]; }; #define BOOT_PATH_NORMAL 0 #define BOOT_PATH_WARM_RESET 1 @@ -316,22 +328,6 @@ enum ddr2_signals { CTRL1, CTRL2, CTRL3, - DQS1, - DQS2, - DQS3, - DQS4, - DQS5, - DQS6, - DQS7, - DQS8, - DQ1, - DQ2, - DQ3, - DQ4, - DQ5, - DQ6, - DQ7, - DQ8 }; #ifndef __BOOTBLOCK__ @@ -346,6 +342,22 @@ void rcven(struct sysinfo *s); u32 fsb2mhz(u32 speed); u32 ddr2mhz(u32 speed); +extern const struct dll_setting default_ddr2_667_ctrl[7]; +extern const struct dll_setting default_ddr2_800_ctrl[7]; +extern const struct dll_setting default_ddr3_800_ctrl[2][7]; +extern const struct dll_setting default_ddr3_1067_ctrl[2][7]; +extern const struct dll_setting default_ddr3_1333_ctrl[2][7]; +extern const struct dll_setting default_ddr2_667_dqs[8]; +extern const struct dll_setting default_ddr2_800_dqs[8]; +extern const struct dll_setting default_ddr3_800_dqs[2][8]; +extern const struct dll_setting default_ddr3_1067_dqs[2][8]; +extern const struct dll_setting default_ddr3_1333_dqs[2][8]; +extern const struct dll_setting default_ddr2_667_dq[8]; +extern const struct dll_setting default_ddr2_800_dq[8]; +extern const struct dll_setting default_ddr3_800_dq[2][8]; +extern const struct dll_setting default_ddr3_1067_dq[2][8]; +extern const struct dll_setting default_ddr3_1333_dq[2][8]; + struct acpi_rsdp; #ifndef __SIMPLE_DEVICE__ unsigned long northbridge_write_acpi_tables(device_t device, unsigned long start, struct acpi_rsdp *rsdp); |