The DBM90T code sets bit 10 in _PSS as part of the control value, but
[coreboot.git] / src / mainboard / amd / pistachio / acpi_tables.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2008 Advanced Micro Devices, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
18  */
19
20 #include <console/console.h>
21 #include <string.h>
22 #include <arch/acpi.h>
23 #include <device/pci.h>
24 #include <device/pci_ids.h>
25 #include <cpu/x86/msr.h>
26 #include <cpu/amd/mtrr.h>
27 #include <cpu/amd/amdk8_sysconf.h>
28
29 #include <arch/cpu.h>
30
31 #define DUMP_ACPI_TABLES 0
32
33 /*
34 * Assume the max pstate number is 8
35 * 0x21(33 bytes) is one package length of _PSS package
36 */
37
38 #define Maxpstate 8
39 #define Defpkglength 0x21
40
41 #if DUMP_ACPI_TABLES == 1
42 static void dump_mem(u32 start, u32 end)
43 {
44
45         u32 i;
46         print_debug("dump_mem:");
47         for (i = start; i < end; i++) {
48                 if ((i & 0xf) == 0) {
49                         printk_debug("\n%08x:", i);
50                 }
51                 printk_debug(" %02x", (u8)*((u8 *)i));
52         }
53         print_debug("\n");
54 }
55 #endif
56
57 extern u8 AmlCode[];
58 extern u8 AmlCode_ssdt[];
59
60 #if ACPI_SSDTX_NUM >= 1
61 extern u8 AmlCode_ssdt2[];
62 extern u8 AmlCode_ssdt3[];
63 extern u8 AmlCode_ssdt4[];
64 extern u8 AmlCode_ssdt5[];
65 #endif
66
67 #define IO_APIC_ADDR    0xfec00000UL
68
69 unsigned long acpi_fill_mcfg(unsigned long current)
70 {
71         /* Just a dummy */
72         return current;
73 }
74
75 unsigned long acpi_fill_madt(unsigned long current)
76 {
77         /* create all subtables for processors */
78         current = acpi_create_madt_lapics(current);
79
80         /* Write SB600 IOAPIC, only one */
81         current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, 2,
82                                            IO_APIC_ADDR, 0);
83
84         current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
85                                                 current, 0, 0, 2, 0);
86         current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
87                                                 current, 0, 9, 9, 0xF);
88         /* 0: mean bus 0--->ISA */
89         /* 0: PIC 0 */
90         /* 2: APIC 2 */
91         /* 5 mean: 0101 --> Edige-triggered, Active high */
92
93         /* create all subtables for processors */
94         /* current = acpi_create_madt_lapic_nmis(current, 5, 1); */
95         /* 1: LINT1 connect to NMI */
96
97         return current;
98 }
99
100 extern void get_bus_conf(void);
101
102 extern void update_ssdt(void *ssdt);
103
104 void update_ssdtx(void *ssdtx, int i)
105 {
106         uint8_t *PCI;
107         uint8_t *HCIN;
108         uint8_t *UID;
109
110         PCI = ssdtx + 0x32;
111         HCIN = ssdtx + 0x39;
112         UID = ssdtx + 0x40;
113
114         if (i < 7) {
115                 *PCI = (uint8_t) ('4' + i - 1);
116         } else {
117                 *PCI = (uint8_t) ('A' + i - 1 - 6);
118         }
119         *HCIN = (uint8_t) i;
120         *UID = (uint8_t) (i + 3);
121
122         /* FIXME: need to update the GSI id in the ssdtx too */
123
124 }
125
126 /*
127 * Details about this algorithm , refert to BDKG 10.5.1
128 * Two parts are included, the another is the DSDT reconstruction process
129 */
130 u32 pstates_algorithm(acpi_header_t * dsdt)
131 {
132         u8 processor_brand[49];
133         u32 *v;
134         struct cpuid_result cpuid1;
135
136         struct power_limit_encoding {
137                 u8 socket_type;
138                 u8 cmp_cap;
139                 u8 pwr_lmt;
140                 u32 power_limit;
141         };
142         u8 Max_fid, Max_vid, Start_fid, Start_vid, Min_fid, Min_vid;
143         u16 Max_feq;
144         u8 Pstate_fid[10];
145         u16 Pstate_feq[10];
146         u8 Pstate_vid[10];
147         u32 Pstate_power[10];
148         u32 Pstate_volt[10];
149         u8 PstateStep, PstateStep_coef;
150         u8 IntPstateSup;
151         u8 Pstate_num;
152         u16 Cur_feq;
153         u8 Cur_fid;
154         u8 cmp_cap, pwr_lmt;
155         u32 power_limit = 0;
156         u8 index;
157         u32 i, j;
158         u32 processor_length, scope_length;
159         msr_t msr;
160         u8 *dsdt_pointer;
161         u8 *pointer1;
162         u8 *pointer2;
163         u8 byte_index;
164         u32 old_dsdt_length, new_dsdt_length;
165         u32 corefeq, power, transitionlatency, busmasterlatency, control,
166             status;
167         u32 new_package_length;
168         u8 sum, checksum;
169         u32 fid_multiplier;
170         static struct power_limit_encoding TDP[20] = {
171                 {0x11, 0x0, 0x8, 62},
172                 {0x11, 0x1, 0x8, 89},
173                 {0x11, 0x1, 0xa, 103},
174                 {0x11, 0x1, 0xc, 125},
175                 {0x11, 0x0, 0x2, 15},
176                 {0x11, 0x0, 0x4, 35},
177                 {0x11, 0x1, 0x2, 35},
178                 {0x11, 0x0, 0x5, 45},
179                 {0x11, 0x1, 0x7, 76},
180                 {0x11, 0x1, 0x6, 65},
181                 {0x11, 0x1, 0x8, 89},
182                 {0x11, 0x0, 0x1, 8},
183                 {0x11, 0x1, 0x1, 22},
184                 {0x12, 0x0, 0x6, 25},
185                 {0x12, 0x0, 0x1, 8},
186                 {0x12, 0x0, 0x2, 9},
187                 {0x12, 0x0, 0x4, 15},
188                 {0x12, 0x0, 0xc, 35},
189                 {0x12, 0x1, 0xc, 35},
190                 {0x12, 0x1, 0x4, 20}
191         };
192
193         /* Get the Processor Brand String using cpuid(0x8000000x) command x=2,3,4 */
194         cpuid1 = cpuid(0x80000002);
195         v = (u32 *) processor_brand;
196         v[0] = cpuid1.eax;
197         v[1] = cpuid1.ebx;
198         v[2] = cpuid1.ecx;
199         v[3] = cpuid1.edx;
200         cpuid1 = cpuid(0x80000003);
201         v[4] = cpuid1.eax;
202         v[5] = cpuid1.ebx;
203         v[6] = cpuid1.ecx;
204         v[7] = cpuid1.edx;
205         cpuid1 = cpuid(0x80000004);
206         v[8] = cpuid1.eax;
207         v[9] = cpuid1.ebx;
208         v[10] = cpuid1.ecx;
209         v[11] = cpuid1.edx;
210         processor_brand[48] = 0;
211         printk_info("processor_brand=%s\n", processor_brand);
212
213         /*
214          * Based on the CPU socket type,cmp_cap and pwr_lmt , get the power limit.
215          * socket_type : 0x10 SocketF; 0x11 AM2/ASB1 ; 0x12 S1G1
216          * cmp_cap : 0x0 SingleCore ; 0x1 DualCore
217          */
218         printk_info("Pstates Algorithm ...\n");
219         cmp_cap =
220             (pci_read_config16(dev_find_slot(0, PCI_DEVFN(0x18, 3)), 0xE8) &
221              0x3000) >> 12;
222         cpuid1 = cpuid(0x80000001);
223         pwr_lmt = ((cpuid1.ebx & 0x1C0) >> 5) | ((cpuid1.ebx & 0x4000) >> 14);
224         for (index = 0; index <= sizeof(TDP) / sizeof(TDP[0]); index++)
225                 if (TDP[index].socket_type == CPU_SOCKET_TYPE &&
226                     TDP[index].cmp_cap == cmp_cap &&
227                     TDP[index].pwr_lmt == pwr_lmt) {
228                         power_limit = TDP[index].power_limit;
229                 }
230
231         /* See if the CPUID(0x80000007) returned EDX[2:1]==11b */
232         cpuid1 = cpuid(0x80000007);
233         if ((cpuid1.edx & 0x6) != 0x6) {
234                 printk_info("No valid set of P-states\n");
235                 return 0;
236         }
237
238         msr = rdmsr(0xc0010042);
239         Max_fid = (msr.lo & 0x3F0000) >> 16;
240         Start_fid = (msr.lo & 0x3F00) >> 8;
241         Max_vid = (msr.hi & 0x3F0000) >> 16;
242         Start_vid = (msr.hi & 0x3F00) >> 8;
243         PstateStep = (msr.hi & 0x1000000) >> 24;
244         IntPstateSup = (msr.hi & 0x20000000) >> 29;
245
246         /*
247          * The P1...P[Min+1] VID need PstateStep to calculate
248          * P[N] = P[N-1]VID + 2^PstateStep
249          * PstateStep_coef = 2^PstateStep
250          */
251         if (PstateStep == 0)
252                 PstateStep_coef = 1;
253         else
254                 PstateStep_coef = 2;
255
256         if (IntPstateSup == 0) {
257                 printk_info("No intermediate P-states are supported\n");
258                 return 0;
259         }
260
261         /* Get the multipier of the fid frequency */
262         /*
263          * Fid multiplier is always 100 revF and revG.
264          */
265         fid_multiplier = 100;
266
267         /*
268          * Formula1:    CPUFreq = FID * fid_multiplier + 800
269          * Formula2:       CPUVolt = 1550 - VID * 25 (mv)
270          * Formula3:       Power = (PwrLmt * P[N]Frequency*(P[N]Voltage^2))/(P[0]Frequency * P[0]Voltage^2))
271          */
272
273         /* Construct P0(P[Max]) state */
274         Pstate_num = 0;
275         Max_feq = Max_fid * fid_multiplier + 800;
276         if (Max_fid == 0x2A && Max_vid != 0x0) {
277                 Min_fid = 0x2;
278                 Pstate_fid[0] = Start_fid + 0xA;        /* Start Frequency + 1GHz */
279                 Pstate_feq[0] = Pstate_fid[0] * fid_multiplier + 800;
280                 Min_vid = Start_vid;
281                 Pstate_vid[0] = Max_vid + 0x2;  /* Maximum Voltage - 50mV */
282                 Pstate_volt[0] = 1550 - Pstate_vid[0] * 25;
283                 Pstate_power[0] = power_limit * 1000;   /* mw */
284                 Pstate_num++;
285         } else {
286                 Min_fid = Start_fid;
287                 Pstate_fid[0] = Max_fid;
288                 Pstate_feq[0] = Max_feq;
289                 Min_vid = Start_vid;
290                 Pstate_vid[0] = Max_vid + 0x2;
291                 Pstate_volt[0] = 1550 - Pstate_vid[0] * 25;
292                 Pstate_power[0] = power_limit * 1000;   /* mw */
293                 Pstate_num++;
294         }
295
296         Cur_feq = Max_feq;
297         Cur_fid = Max_fid;
298         /* Construct P1 state */
299         if (((Max_fid & 0x1) != 0) && ((Max_fid - 0x1) >= (Min_fid + 0x8))) {   /* odd value */
300                 Pstate_fid[1] = Max_fid - 0x1;
301                 Pstate_feq[1] = Pstate_fid[1] * fid_multiplier + 800;
302                 Cur_fid = Pstate_fid[1];
303                 Cur_feq = Pstate_feq[1];
304                 if (((Pstate_vid[0] & 0x1) != 0) && ((Pstate_vid[0] - 0x1) < Min_vid)) {        /* odd value */
305                         Pstate_vid[1] = Pstate_vid[0] + 0x1;
306                         Pstate_volt[1] = 1550 - Pstate_vid[1] * 25;
307                         Pstate_power[1] =
308                             (unsigned long long)Pstate_power[0] *
309                             Pstate_feq[1] * Pstate_volt[1] * Pstate_volt[1] /
310                             (Pstate_feq[0] * Pstate_volt[0] * Pstate_volt[0]);
311                 }
312                 if (((Pstate_vid[0] & 0x1) == 0) && ((Pstate_vid[0] - 0x1) < Min_vid)) {        /* even value */
313                         Pstate_vid[1] = Pstate_vid[0] + PstateStep_coef;
314                         Pstate_volt[1] = 1550 - Pstate_vid[1] * 25;
315                         Pstate_power[1] =
316                             (unsigned long long)Pstate_power[0] *
317                             Pstate_feq[1] * Pstate_volt[1] * Pstate_volt[1] /
318                             (Pstate_feq[0] * Pstate_volt[0] * Pstate_volt[0]);
319                 }
320                 Pstate_num++;
321         }
322
323         if (((Max_fid & 0x1) == 0) && ((Max_fid - 0x2) >= (Min_fid + 0x8))) {   /* even value */
324                 Pstate_fid[1] = Max_fid - 0x2;
325                 Pstate_feq[1] = Pstate_fid[1] * fid_multiplier + 800;
326                 Cur_fid = Pstate_fid[1];
327                 Cur_feq = Pstate_feq[1];
328                 if (((Pstate_vid[0] & 0x1) != 0) && ((Pstate_vid[0] - 0x1) < Min_vid)) {        /* odd value */
329                         Pstate_vid[1] = Pstate_vid[0] + 0x1;
330                         Pstate_volt[1] = 1550 - Pstate_vid[1] * 25;
331                         Pstate_power[1] =
332                             (unsigned long long)Pstate_power[0] *
333                             Pstate_feq[1] * Pstate_volt[1] * Pstate_volt[1] /
334                             (Pstate_feq[0] * Pstate_volt[0] * Pstate_volt[0]);
335                 }
336                 if (((Pstate_vid[0] & 0x1) == 0) && ((Pstate_vid[0] - 0x1) < Min_vid)) {        /* even value */
337                         Pstate_vid[1] = Pstate_vid[0] + PstateStep_coef;
338                         Pstate_volt[1] = 1550 - Pstate_vid[1] * 25;
339                         Pstate_power[1] =
340                             (unsigned long long)Pstate_power[0] *
341                             Pstate_feq[1] * Pstate_volt[1] * Pstate_volt[1] /
342                             (Pstate_feq[0] * Pstate_volt[0] * Pstate_volt[0]);
343                 }
344
345                 Pstate_num++;
346         }
347
348         /* Construct P2...P[Min-1] state */
349         Cur_fid = Cur_fid - 0x2;
350         Cur_feq = Cur_fid * fid_multiplier + 800;
351         while (Cur_feq >= ((Min_fid * fid_multiplier) + 800) * 2) {
352                 Pstate_fid[Pstate_num] = Cur_fid;
353                 Pstate_feq[Pstate_num] =
354                     Pstate_fid[Pstate_num] * fid_multiplier + 800;
355                 Cur_fid = Cur_fid - 0x2;
356                 Cur_feq = Cur_fid * fid_multiplier + 800;
357                 if (Pstate_vid[Pstate_num - 1] >= Min_vid) {
358                         Pstate_vid[Pstate_num] = Pstate_vid[Pstate_num - 1];
359                         Pstate_volt[Pstate_num] = Pstate_volt[Pstate_num - 1];
360                         Pstate_power[Pstate_num] = Pstate_power[Pstate_num - 1];
361                 } else {
362                         Pstate_vid[Pstate_num] =
363                             Pstate_vid[Pstate_num - 1] + PstateStep_coef;
364                         Pstate_volt[Pstate_num] =
365                             1550 - Pstate_vid[Pstate_num] * 25;
366                         Pstate_power[Pstate_num] =
367                             (unsigned long long)Pstate_power[0] *
368                             Pstate_feq[Pstate_num] * Pstate_volt[Pstate_num] *
369                             Pstate_volt[Pstate_num] / (Pstate_feq[0] *
370                                                        Pstate_volt[0] *
371                                                        Pstate_volt[0]);
372                 }
373                 Pstate_num++;
374         }
375
376         /* Constuct P[Min] State */
377         if (Max_fid == 0x2A && Max_vid != 0x0) {
378                 Pstate_fid[Pstate_num] = 0x2;
379                 Pstate_feq[Pstate_num] =
380                     Pstate_fid[Pstate_num] * fid_multiplier + 800;
381                 Pstate_vid[Pstate_num] = Min_vid;
382                 Pstate_volt[Pstate_num] = 1550 - Pstate_vid[Pstate_num] * 25;
383                 Pstate_power[Pstate_num] =
384                     (unsigned long long)Pstate_power[0] *
385                     Pstate_feq[Pstate_num] * Pstate_volt[Pstate_num] *
386                     Pstate_volt[Pstate_num] / (Pstate_feq[0] * Pstate_volt[0] *
387                                                Pstate_volt[0]);
388                 Pstate_num++;
389         } else {
390                 Pstate_fid[Pstate_num] = Start_fid;
391                 Pstate_feq[Pstate_num] =
392                     Pstate_fid[Pstate_num] * fid_multiplier + 800;
393                 Pstate_vid[Pstate_num] = Min_vid;
394                 Pstate_volt[Pstate_num] = 1550 - Pstate_vid[Pstate_num] * 25;
395                 Pstate_power[Pstate_num] =
396                     (unsigned long long)Pstate_power[0] *
397                     Pstate_feq[Pstate_num] * Pstate_volt[Pstate_num] *
398                     Pstate_volt[Pstate_num] / (Pstate_feq[0] * Pstate_volt[0] *
399                                                Pstate_volt[0]);
400                 Pstate_num++;
401         }
402
403         /* Print Pstate freq,vid,volt,power */
404
405         for (index = 0; index < Pstate_num; index++) {
406                 printk_info("Pstate_freq[%d] = %dMHz\t", index,
407                             Pstate_feq[index]);
408                 printk_info("Pstate_vid[%d] = %d\t", index, Pstate_vid[index]);
409                 printk_info("Pstate_volt[%d] = %dmv\t", index,
410                             Pstate_volt[index]);
411                 printk_info("Pstate_power[%d] = %dmw\n", index,
412                             Pstate_power[index]);
413         }
414
415         /*
416          * Modify the DSDT Table to put the actural _PSS package
417          * corefeq-->Pstate_feq[index]
418          * power-->Pstate_power[index]
419          * transitionlatency-->0x64
420          * busmasterlatency-->0x7,
421          * control--> 0xE8202800| Pstate_vid[index]<<6 | Pstate_fid[index]
422          * status --> Pstate_vid[index]<<6 | Pstate_fid[index]
423          * Get the _PSS control method Sig.
424          */
425
426         dsdt_pointer = (u8 *) dsdt;
427         old_dsdt_length = dsdt->length;
428         new_dsdt_length = old_dsdt_length;
429         printk_info("DSDT reconstruction...\n");
430         for (i = 0x20; i < new_dsdt_length; i++)
431                 if ((*(dsdt_pointer + i) == '_')
432                     && (*(dsdt_pointer + i + 1) == 'P')
433                     && (*(dsdt_pointer + i + 2) == 'S')
434                     && (*(dsdt_pointer + i + 3) == 'S')) {
435
436                         if ((*(dsdt_pointer + i + 4) !=
437                              0x12) | (*(dsdt_pointer + i + 5) !=
438                                       0x4B) | (*(dsdt_pointer + i + 6) !=
439                                                0x10)) {
440                                 printk_info
441                                     ("Error:No _PSS package leader byte!\n");
442                         } else {
443                                 new_package_length =
444                                     0x10B - Defpkglength * (Maxpstate -
445                                                             Pstate_num);
446                                 /* two Pstates length will larger than 63, so we need not worry about the length */
447                                 if (new_package_length > 63) {
448                                         *(dsdt_pointer + i + 5) =
449                                             0x40 | (new_package_length & 0xf);
450                                         *(dsdt_pointer + i + 6) =
451                                             (new_package_length & 0xff0) >> 4;
452                                 }
453                                 *(dsdt_pointer + i + 7) = Pstate_num;
454                         }
455
456                         if ((*(dsdt_pointer + i + 8) !=
457                              0x12) | (*(dsdt_pointer + i + 9) !=
458                                       0x20) | (*(dsdt_pointer + i + 10) != 0x6))
459                                 printk_info
460                                     ("Error:No package leader for the first Pstate!\n");
461                         for (index = 0; index < Pstate_num; index++) {
462                                 corefeq = Pstate_feq[index];
463                                 power = Pstate_power[index];
464                                 transitionlatency = 0x64;
465                                 busmasterlatency = 0x7;
466                                 control =
467                                     (0x3 << 30) | /* IRT */
468                                     (0x2 << 28) | /* RVO */
469                                     (0x1 << 27) | /* ExtType */
470                                     (0x2 << 20) | /* PLL_LOCK_TIME */
471                                     (0x0 << 18) | /* MVS */
472                                     (0x5 << 11) | /* VST */
473                                     (Pstate_vid[index] << 6) |
474                                     Pstate_fid[index];
475                                 status =
476                                     (Pstate_vid[index] << 6) |
477                                     Pstate_fid[index];
478                                 for (byte_index = 0; byte_index < 4;
479                                      byte_index++) {
480                                         *(dsdt_pointer + i + 0xC +
481                                           Defpkglength * index + byte_index) =
482                    corefeq >> (8 * byte_index);
483                                         *(dsdt_pointer + i + 0xC +
484                                           Defpkglength * index + 0x5 +
485                                           byte_index) =
486                    power >> (8 * byte_index);
487                                         *(dsdt_pointer + i + 0xC +
488                                           Defpkglength * index + 0x5 * 2 +
489                                           byte_index) =
490                    transitionlatency >> (8 * byte_index);
491                                         *(dsdt_pointer + i + 0xC +
492                                           Defpkglength * index + 0x5 * 3 +
493                                           byte_index) =
494                    busmasterlatency >> (8 * byte_index);
495                                         *(dsdt_pointer + i + 0xC +
496                                           Defpkglength * index + 0x5 * 4 +
497                                           byte_index) =
498                    control >> (8 * byte_index);
499                                         *(dsdt_pointer + i + 0xC +
500                                           Defpkglength * index + 0x5 * 5 +
501                                           byte_index) =
502                    status >> (8 * byte_index);
503                                 }
504                         }
505                         pointer1 =
506                             dsdt_pointer + i + 8 + Pstate_num * Defpkglength;
507                         pointer2 =
508                             dsdt_pointer + i + 8 + Maxpstate * Defpkglength;
509                         while (pointer2 < dsdt_pointer + new_dsdt_length) {
510                                 *pointer1 = *pointer2;
511                                 pointer1++;
512                                 pointer2++;
513                         }
514                         /* Recalcute the DSDT length */
515                         new_dsdt_length =
516                             new_dsdt_length - Defpkglength * (Maxpstate -
517                                                               Pstate_num);
518
519                         /* Search the first processor(CPUx) item and recalculate the processor length */
520                         for (j = 0; (dsdt_pointer + i - j) > dsdt_pointer; j++) {
521                                 if ((*(dsdt_pointer + i - j) == 'C')
522                                     && (*(dsdt_pointer + i - j + 1) == 'P')
523                                     && (*(dsdt_pointer + i - j + 2) == 'U')) {
524                                         processor_length =
525                                             ((*(dsdt_pointer + i - j - 1) << 4)
526                                              | (*(dsdt_pointer + i - j - 2) &
527                                                 0xf));
528                                         processor_length =
529                                             processor_length -
530                                             Defpkglength * (Maxpstate -
531                                                             Pstate_num);
532                                         *(dsdt_pointer + i - j - 2) =
533                                             (processor_length & 0xf) | 0x40;
534                                         *(dsdt_pointer + i - j - 1) =
535                                             (processor_length & 0xff0) >> 4;
536                                         break;
537                                 }
538                         }
539
540                         /* Search the first scope(_PR_) item and recalculate the scope length */
541                         for (j = 0; (dsdt_pointer + i - j) > dsdt_pointer; j++) {
542                                 if ((*(dsdt_pointer + i - j) == '_')
543                                     && (*(dsdt_pointer + i - j + 1) == 'P')
544                                     && (*(dsdt_pointer + i - j + 2) == 'R')
545                                     && (*(dsdt_pointer + i - j + 3) == '_')) {
546                                         scope_length =
547                                             ((*(dsdt_pointer + i - j - 1) << 4)
548                                              | (*(dsdt_pointer + i - j - 2) &
549                                                 0xf));
550                                         scope_length =
551                                             scope_length -
552                                             Defpkglength * (Maxpstate -
553                                                             Pstate_num);
554                                         *(dsdt_pointer + i - j - 2) =
555                                             (scope_length & 0xf) | 0x40;
556                                         *(dsdt_pointer + i - j - 1) =
557                                             (scope_length & 0xff0) >> 4;
558                                         break;
559                                 }
560                         }
561
562                 }
563
564         /* Recalculate the DSDT length and fill back to the table */
565         *(dsdt_pointer + 0x4) = new_dsdt_length;
566         *(dsdt_pointer + 0x5) = new_dsdt_length >> 8;
567
568         /*
569          * Recalculate the DSDT checksum and fill back to the table
570          * We must make sure the sum of the whole table is 0
571          */
572         sum = 0;
573         for (i = 0; i < new_dsdt_length; i++)
574                 if (i != 9)
575                         sum = sum + *(dsdt_pointer + i);
576         checksum = 0x100 - sum;
577         *(dsdt_pointer + 0x9) = checksum;
578
579         /*Check the DSDT Table */
580         /*
581          * printk_info("The new DSDT table length is %x\n", new_dsdt_length);
582          * printk_info("Details is as below:\n");
583          * for(i=0; i< new_dsdt_length; i++){
584          *      printk_info("%x\t",(unsigned char)*(dsdt_pointer+i));
585          *      if( ((i+1)&0x7) == 0x0)
586          *              printk_info("**0x%x**\n",i-7);
587          *}
588          */
589
590         return 1;
591
592 }
593
594 unsigned long write_acpi_tables(unsigned long start)
595 {
596         unsigned long current;
597         acpi_rsdp_t *rsdp;
598         acpi_rsdt_t *rsdt;
599         acpi_hpet_t *hpet;
600         acpi_madt_t *madt;
601         acpi_fadt_t *fadt;
602         acpi_facs_t *facs;
603         acpi_header_t *dsdt;
604         acpi_header_t *ssdt;
605
606         get_bus_conf();         /* it will get sblk, pci1234, hcdn, and sbdn */
607
608         /* Align ACPI tables to 16byte */
609         start = (start + 0x0f) & -0x10;
610         current = start;
611
612         printk_info("ACPI: Writing ACPI tables at %lx...\n", start);
613
614         /* We need at least an RSDP and an RSDT Table */
615         rsdp = (acpi_rsdp_t *) current;
616         current += sizeof(acpi_rsdp_t);
617         rsdt = (acpi_rsdt_t *) current;
618         current += sizeof(acpi_rsdt_t);
619
620         /* clear all table memory */
621         memset((void *)start, 0, current - start);
622
623         acpi_write_rsdp(rsdp, rsdt);
624         acpi_write_rsdt(rsdt);
625
626         /*
627          * We explicitly add these tables later on:
628          */
629         /* If we want to use HPET Timers Linux wants an MADT */
630         printk_debug("ACPI:    * HPET\n");
631         hpet = (acpi_hpet_t *) current;
632         current += sizeof(acpi_hpet_t);
633         acpi_create_hpet(hpet);
634         acpi_add_table(rsdt, hpet);
635
636         printk_debug("ACPI:    * MADT\n");
637         madt = (acpi_madt_t *) current;
638         acpi_create_madt(madt);
639         current += madt->header.length;
640         acpi_add_table(rsdt, madt);
641
642 #if 0
643         /* SRAT */
644         printk_debug("ACPI:    * SRAT\n");
645         srat = (acpi_srat_t *) current;
646         acpi_create_srat(srat);
647         current += srat->header.length;
648         acpi_add_table(rsdt, srat);
649
650         /* SLIT */
651         printk_debug("ACPI:    * SLIT\n");
652         slit = (acpi_slit_t *) current;
653         acpi_create_slit(slit);
654         current += slit->header.length;
655         acpi_add_table(rsdt, slit);
656 #endif
657
658         /* SSDT */
659         printk_debug("ACPI:    * SSDT\n");
660         ssdt = (acpi_header_t *) current;
661         current += ((acpi_header_t *) AmlCode_ssdt)->length;
662         memcpy((void *)ssdt, (void *)AmlCode_ssdt,
663                ((acpi_header_t *) AmlCode_ssdt)->length);
664         /* Here you need to set value in pci1234, sblk and sbdn in get_bus_conf.c */
665         update_ssdt((void *)ssdt);
666         /* recalculate checksum */
667         ssdt->checksum = 0;
668         ssdt->checksum = acpi_checksum((u8 *)ssdt, ssdt->length);
669         acpi_add_table(rsdt, ssdt);
670
671 #if ACPI_SSDTX_NUM >= 1
672
673         /* same htio, but different position? We may have to copy, change HCIN, and recalculate the checknum and add_table */
674
675         for (i = 1; i < sysconf.hc_possible_num; i++) { /* 0: is hc sblink */
676                 if ((sysconf.pci1234[i] & 1) != 1)
677                         continue;
678                 uint8_t c;
679                 if (i < 7) {
680                         c = (uint8_t) ('4' + i - 1);
681                 } else {
682                         c = (uint8_t) ('A' + i - 1 - 6);
683                 }
684                 printk_debug("ACPI:    * SSDT for PCI%c Aka hcid = %d\n", c, sysconf.hcid[i]);  /* pci0 and pci1 are in dsdt */
685                 current = (current + 0x07) & -0x08;
686                 ssdtx = (acpi_header_t *) current;
687                 switch (sysconf.hcid[i]) {
688                 case 1: /* 8132 */
689                         p = AmlCode_ssdt2;
690                         break;
691                 case 2: /* 8151 */
692                         p = AmlCode_ssdt3;
693                         break;
694                 case 3: /* 8131 */
695                         p = AmlCode_ssdt4;
696                         break;
697                 default:
698                         /* HTX no io apic */
699                         p = AmlCode_ssdt5;
700                         break;
701                 }
702                 current += ((acpi_header_t *) p)->length;
703                 memcpy((void *)ssdtx, (void *)p, ((acpi_header_t *) p)->length);
704                 update_ssdtx((void *)ssdtx, i);
705                 ssdtx->checksum = 0;
706                 ssdtx->checksum =
707                     acpi_checksum((u8 *)ssdtx, ssdtx->length);
708                 acpi_add_table(rsdt, ssdtx);
709         }
710 #endif
711
712         /* FACS */
713         printk_debug("ACPI:    * FACS\n");
714         facs = (acpi_facs_t *) current;
715         current += sizeof(acpi_facs_t);
716         acpi_create_facs(facs);
717
718         /* DSDT */
719         printk_debug("ACPI:    * DSDT\n");
720         dsdt = (acpi_header_t *) current;
721         memcpy((void *)dsdt, (void *)AmlCode,
722                ((acpi_header_t *) AmlCode)->length);
723         if (!pstates_algorithm(dsdt))
724                 printk_debug("pstates_algorithm error!\n");
725         else
726                 printk_debug("pstates_algorithm success.\n");
727
728         current += dsdt->length;
729         printk_debug("ACPI:    * DSDT @ %08x Length %x\n", dsdt, dsdt->length);
730         /* FDAT */
731         printk_debug("ACPI:    * FADT\n");
732         fadt = (acpi_fadt_t *) current;
733         current += sizeof(acpi_fadt_t);
734
735         acpi_create_fadt(fadt, facs, dsdt);
736         acpi_add_table(rsdt, fadt);
737
738 #if DUMP_ACPI_TABLES == 1
739         printk_debug("rsdp\n");
740         dump_mem(rsdp, ((void *)rsdp) + sizeof(acpi_rsdp_t));
741
742         printk_debug("rsdt\n");
743         dump_mem(rsdt, ((void *)rsdt) + sizeof(acpi_rsdt_t));
744
745         printk_debug("madt\n");
746         dump_mem(madt, ((void *)madt) + madt->header.length);
747
748         printk_debug("srat\n");
749         dump_mem(srat, ((void *)srat) + srat->header.length);
750
751         printk_debug("slit\n");
752         dump_mem(slit, ((void *)slit) + slit->header.length);
753
754         printk_debug("ssdt\n");
755         dump_mem(ssdt, ((void *)ssdt) + ssdt->length);
756
757         printk_debug("fadt\n");
758         dump_mem(fadt, ((void *)fadt) + fadt->header.length);
759 #endif
760
761         printk_info("ACPI: done.\n");
762         return current;
763 }