eb3433cc619e43a258f2a12dd3a4f2663d381edc
[coreboot.git] / src / mainboard / amd / dbm690t / 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          * In RevG, 100MHz step is added
264          */
265         cpuid1 = cpuid(0x80000007);
266         fid_multiplier = ((cpuid1.edx & 0x40) >> 6) * 100;
267
268         /*
269          * Formula1:    CPUFreq = FID * fid_multiplier + 800
270          * Formula2:       CPUVolt = 1550 - VID * 25 (mv)
271          * Formula3:       Power = (PwrLmt * P[N]Frequency*(P[N]Voltage^2))/(P[0]Frequency * P[0]Voltage^2))
272          */
273
274         /* Construct P0(P[Max]) state */
275         Pstate_num = 0;
276         Max_feq = Max_fid * fid_multiplier + 800;
277         if (Max_fid == 0x2A && Max_vid != 0x0) {
278                 Min_fid = 0x2;
279                 Pstate_fid[0] = Start_fid + 0xA;        /* Start Frequency + 1GHz */
280                 Pstate_feq[0] = Pstate_fid[0] * fid_multiplier + 800;
281                 Min_vid = Start_vid;
282                 Pstate_vid[0] = Max_vid + 0x2;  /* Maximum Voltage - 50mV */
283                 Pstate_volt[0] = 1550 - Pstate_vid[0] * 25;
284                 Pstate_power[0] = power_limit * 1000;   /* mw */
285                 Pstate_num++;
286         } else {
287                 Min_fid = Start_fid;
288                 Pstate_fid[0] = Max_fid;
289                 Pstate_feq[0] = Max_feq;
290                 Min_vid = Start_vid;
291                 Pstate_vid[0] = Max_vid + 0x2;
292                 Pstate_volt[0] = 1550 - Pstate_vid[0] * 25;
293                 Pstate_power[0] = power_limit * 1000;   /* mw */
294                 Pstate_num++;
295         }
296
297         Cur_feq = Max_feq;
298         Cur_fid = Max_fid;
299         /* Construct P1 state */
300         if (((Max_fid & 0x1) != 0) && ((Max_fid - 0x1) >= (Min_fid + 0x8))) {   /* odd value */
301                 Pstate_fid[1] = Max_fid - 0x1;
302                 Pstate_feq[1] = Pstate_fid[1] * fid_multiplier + 800;
303                 Cur_fid = Pstate_fid[1];
304                 Cur_feq = Pstate_feq[1];
305                 if (((Pstate_vid[0] & 0x1) != 0) && ((Pstate_vid[0] - 0x1) < Min_vid)) {        /* odd value */
306                         Pstate_vid[1] = Pstate_vid[0] + 0x1;
307                         Pstate_volt[1] = 1550 - Pstate_vid[1] * 25;
308                         Pstate_power[1] =
309                             (unsigned long long)Pstate_power[0] *
310                             Pstate_feq[1] * Pstate_volt[1] * Pstate_volt[1] /
311                             (Pstate_feq[0] * Pstate_volt[0] * Pstate_volt[0]);
312                 }
313                 if (((Pstate_vid[0] & 0x1) == 0) && ((Pstate_vid[0] - 0x1) < Min_vid)) {        /* even value */
314                         Pstate_vid[1] = Pstate_vid[0] + PstateStep_coef;
315                         Pstate_volt[1] = 1550 - Pstate_vid[1] * 25;
316                         Pstate_power[1] =
317                             (unsigned long long)Pstate_power[0] *
318                             Pstate_feq[1] * Pstate_volt[1] * Pstate_volt[1] /
319                             (Pstate_feq[0] * Pstate_volt[0] * Pstate_volt[0]);
320                 }
321                 Pstate_num++;
322         }
323
324         if (((Max_fid & 0x1) == 0) && ((Max_fid - 0x2) >= (Min_fid + 0x8))) {   /* even value */
325                 Pstate_fid[1] = Max_fid - 0x2;
326                 Pstate_feq[1] = Pstate_fid[1] * fid_multiplier + 800;
327                 Cur_fid = Pstate_fid[1];
328                 Cur_feq = Pstate_feq[1];
329                 if (((Pstate_vid[0] & 0x1) != 0) && ((Pstate_vid[0] - 0x1) < Min_vid)) {        /* odd value */
330                         Pstate_vid[1] = Pstate_vid[0] + 0x1;
331                         Pstate_volt[1] = 1550 - Pstate_vid[1] * 25;
332                         Pstate_power[1] =
333                             (unsigned long long)Pstate_power[0] *
334                             Pstate_feq[1] * Pstate_volt[1] * Pstate_volt[1] /
335                             (Pstate_feq[0] * Pstate_volt[0] * Pstate_volt[0]);
336                 }
337                 if (((Pstate_vid[0] & 0x1) == 0) && ((Pstate_vid[0] - 0x1) < Min_vid)) {        /* even value */
338                         Pstate_vid[1] = Pstate_vid[0] + PstateStep_coef;
339                         Pstate_volt[1] = 1550 - Pstate_vid[1] * 25;
340                         Pstate_power[1] =
341                             (unsigned long long)Pstate_power[0] *
342                             Pstate_feq[1] * Pstate_volt[1] * Pstate_volt[1] /
343                             (Pstate_feq[0] * Pstate_volt[0] * Pstate_volt[0]);
344                 }
345
346                 Pstate_num++;
347         }
348
349         /* Construct P2...P[Min-1] state */
350         Cur_fid = Cur_fid - 0x2;
351         Cur_feq = Cur_fid * fid_multiplier + 800;
352         while (Cur_feq >= ((Min_fid * fid_multiplier) + 800) * 2) {
353                 Pstate_fid[Pstate_num] = Cur_fid;
354                 Pstate_feq[Pstate_num] =
355                     Pstate_fid[Pstate_num] * fid_multiplier + 800;
356                 Cur_fid = Cur_fid - 0x2;
357                 Cur_feq = Cur_fid * fid_multiplier + 800;
358                 if (Pstate_vid[Pstate_num - 1] >= Min_vid) {
359                         Pstate_vid[Pstate_num] = Pstate_vid[Pstate_num - 1];
360                         Pstate_volt[Pstate_num] = Pstate_volt[Pstate_num - 1];
361                         Pstate_power[Pstate_num] = Pstate_power[Pstate_num - 1];
362                 } else {
363                         Pstate_vid[Pstate_num] =
364                             Pstate_vid[Pstate_num - 1] + PstateStep_coef;
365                         Pstate_volt[Pstate_num] =
366                             1550 - Pstate_vid[Pstate_num] * 25;
367                         Pstate_power[Pstate_num] =
368                             (unsigned long long)Pstate_power[0] *
369                             Pstate_feq[Pstate_num] * Pstate_volt[Pstate_num] *
370                             Pstate_volt[Pstate_num] / (Pstate_feq[0] *
371                                                        Pstate_volt[0] *
372                                                        Pstate_volt[0]);
373                 }
374                 Pstate_num++;
375         }
376
377         /* Constuct P[Min] State */
378         if (Max_fid == 0x2A && Max_vid != 0x0) {
379                 Pstate_fid[Pstate_num] = 0x2;
380                 Pstate_feq[Pstate_num] =
381                     Pstate_fid[Pstate_num] * fid_multiplier + 800;
382                 Pstate_vid[Pstate_num] = Min_vid;
383                 Pstate_volt[Pstate_num] = 1550 - Pstate_vid[Pstate_num] * 25;
384                 Pstate_power[Pstate_num] =
385                     (unsigned long long)Pstate_power[0] *
386                     Pstate_feq[Pstate_num] * Pstate_volt[Pstate_num] *
387                     Pstate_volt[Pstate_num] / (Pstate_feq[0] * Pstate_volt[0] *
388                                                Pstate_volt[0]);
389                 Pstate_num++;
390         } else {
391                 Pstate_fid[Pstate_num] = Start_fid;
392                 Pstate_feq[Pstate_num] =
393                     Pstate_fid[Pstate_num] * fid_multiplier + 800;
394                 Pstate_vid[Pstate_num] = Min_vid;
395                 Pstate_volt[Pstate_num] = 1550 - Pstate_vid[Pstate_num] * 25;
396                 Pstate_power[Pstate_num] =
397                     (unsigned long long)Pstate_power[0] *
398                     Pstate_feq[Pstate_num] * Pstate_volt[Pstate_num] *
399                     Pstate_volt[Pstate_num] / (Pstate_feq[0] * Pstate_volt[0] *
400                                                Pstate_volt[0]);
401                 Pstate_num++;
402         }
403
404         /* Print Pstate feq,vid,volt,power */
405
406         for (index = 0; index < Pstate_num; index++) {
407                 printk_info("Pstate_feq[%d] = %dMHz\t", index,
408                             Pstate_feq[index]);
409                 printk_info("Pstate_vid[%d] = %d\t", index, Pstate_vid[index]);
410                 printk_info("Pstate_volt[%d] = %dmv\t", index,
411                             Pstate_volt[index]);
412                 printk_info("Pstate_power[%d] = %dmw\n", index,
413                             Pstate_power[index]);
414         }
415
416         /*
417          * Modify the DSDT Table to put the actural _PSS package
418          * corefeq-->Pstate_feq[index] power-->Pstate_power[index] transitionlatency-->0x64 busmasterlatency-->0x7,
419          * control-->0xE8202C00| Pstate_vid[index]<<6 | Pstate_fid[index]
420          * status --> Pstate_vid[index]<<6 | Pstate_fid[index]
421          * Get the _PSS control method Sig.
422          */
423
424         dsdt_pointer = (u8 *) dsdt;
425         old_dsdt_length = dsdt->length;
426         new_dsdt_length = old_dsdt_length;
427         printk_info("DSDT reconstruction...\n");
428         for (i = 0x20; i < new_dsdt_length; i++)
429                 if ((*(dsdt_pointer + i) == '_')
430                     && (*(dsdt_pointer + i + 1) == 'P')
431                     && (*(dsdt_pointer + i + 2) == 'S')
432                     && (*(dsdt_pointer + i + 3) == 'S')) {
433
434                         if ((*(dsdt_pointer + i + 4) !=
435                              0x12) | (*(dsdt_pointer + i + 5) !=
436                                       0x4B) | (*(dsdt_pointer + i + 6) !=
437                                                0x10)) {
438                                 printk_info
439                                     ("Error:No _PSS package leader byte!\n");
440                         } else {
441                                 new_package_length =
442                                     0x10B - Defpkglength * (Maxpstate -
443                                                             Pstate_num);
444                                 /* two Pstates length will larger than 63, so we need not worry about the length */
445                                 if (new_package_length > 63) {
446                                         *(dsdt_pointer + i + 5) =
447                                             0x40 | (new_package_length & 0xf);
448                                         *(dsdt_pointer + i + 6) =
449                                             (new_package_length & 0xff0) >> 4;
450                                 }
451                                 *(dsdt_pointer + i + 7) = Pstate_num;
452                         }
453
454                         if ((*(dsdt_pointer + i + 8) !=
455                              0x12) | (*(dsdt_pointer + i + 9) !=
456                                       0x20) | (*(dsdt_pointer + i + 10) != 0x6))
457                                 printk_info
458                                     ("Error:No package leader for the first Pstate!\n");
459                         for (index = 0; index < Pstate_num; index++) {
460                                 corefeq = Pstate_feq[index];
461                                 power = Pstate_power[index];
462                                 transitionlatency = 0x64;
463                                 busmasterlatency = 0x7;
464                                 control =
465                                     0xE8202C00 | (Pstate_vid[index] << 6) |
466                                     Pstate_fid[index];
467                                 status =
468                                     (Pstate_vid[index] << 6) |
469                                     Pstate_fid[index];
470                                 for (byte_index = 0; byte_index < 4;
471                                      byte_index++) {
472                                         *(dsdt_pointer + i + 0xC +
473                                           Defpkglength * index + byte_index) =
474                    corefeq >> (8 * byte_index);
475                                         *(dsdt_pointer + i + 0xC +
476                                           Defpkglength * index + 0x5 +
477                                           byte_index) =
478                    power >> (8 * byte_index);
479                                         *(dsdt_pointer + i + 0xC +
480                                           Defpkglength * index + 0x5 * 2 +
481                                           byte_index) =
482                    transitionlatency >> (8 * byte_index);
483                                         *(dsdt_pointer + i + 0xC +
484                                           Defpkglength * index + 0x5 * 3 +
485                                           byte_index) =
486                    busmasterlatency >> (8 * byte_index);
487                                         *(dsdt_pointer + i + 0xC +
488                                           Defpkglength * index + 0x5 * 4 +
489                                           byte_index) =
490                    control >> (8 * byte_index);
491                                         *(dsdt_pointer + i + 0xC +
492                                           Defpkglength * index + 0x5 * 5 +
493                                           byte_index) =
494                    status >> (8 * byte_index);
495                                 }
496                         }
497                         pointer1 =
498                             dsdt_pointer + i + 8 + Pstate_num * Defpkglength;
499                         pointer2 =
500                             dsdt_pointer + i + 8 + Maxpstate * Defpkglength;
501                         while (pointer2 < dsdt_pointer + new_dsdt_length) {
502                                 *pointer1 = *pointer2;
503                                 pointer1++;
504                                 pointer2++;
505                         }
506                         /* Recalcute the DSDT length */
507                         new_dsdt_length =
508                             new_dsdt_length - Defpkglength * (Maxpstate -
509                                                               Pstate_num);
510
511                         /* Search the first processor(CPUx) item and recalculate the processor length */
512                         for (j = 0; (dsdt_pointer + i - j) > dsdt_pointer; j++) {
513                                 if ((*(dsdt_pointer + i - j) == 'C')
514                                     && (*(dsdt_pointer + i - j + 1) == 'P')
515                                     && (*(dsdt_pointer + i - j + 2) == 'U')) {
516                                         processor_length =
517                                             ((*(dsdt_pointer + i - j - 1) << 4)
518                                              | (*(dsdt_pointer + i - j - 2) &
519                                                 0xf));
520                                         processor_length =
521                                             processor_length -
522                                             Defpkglength * (Maxpstate -
523                                                             Pstate_num);
524                                         *(dsdt_pointer + i - j - 2) =
525                                             (processor_length & 0xf) | 0x40;
526                                         *(dsdt_pointer + i - j - 1) =
527                                             (processor_length & 0xff0) >> 4;
528                                         break;
529                                 }
530                         }
531
532                         /* Search the first scope(_PR_) item and recalculate the scope length */
533                         for (j = 0; (dsdt_pointer + i - j) > dsdt_pointer; j++) {
534                                 if ((*(dsdt_pointer + i - j) == '_')
535                                     && (*(dsdt_pointer + i - j + 1) == 'P')
536                                     && (*(dsdt_pointer + i - j + 2) == 'R')
537                                     && (*(dsdt_pointer + i - j + 3) == '_')) {
538                                         scope_length =
539                                             ((*(dsdt_pointer + i - j - 1) << 4)
540                                              | (*(dsdt_pointer + i - j - 2) &
541                                                 0xf));
542                                         scope_length =
543                                             scope_length -
544                                             Defpkglength * (Maxpstate -
545                                                             Pstate_num);
546                                         *(dsdt_pointer + i - j - 2) =
547                                             (scope_length & 0xf) | 0x40;
548                                         *(dsdt_pointer + i - j - 1) =
549                                             (scope_length & 0xff0) >> 4;
550                                         break;
551                                 }
552                         }
553
554                 }
555
556         /* Recalculate the DSDT length and fill back to the table */
557         *(dsdt_pointer + 0x4) = new_dsdt_length;
558         *(dsdt_pointer + 0x5) = new_dsdt_length >> 8;
559
560         /*
561          * Recalculate the DSDT checksum and fill back to the table
562          * We must make sure the sum of the whole table is 0
563          */
564         sum = 0;
565         for (i = 0; i < new_dsdt_length; i++)
566                 if (i != 9)
567                         sum = sum + *(dsdt_pointer + i);
568         checksum = 0x100 - sum;
569         *(dsdt_pointer + 0x9) = checksum;
570
571         /*Check the DSDT Table */
572         /*
573          * printk_info("The new DSDT table length is %x\n", new_dsdt_length);
574          * printk_info("Details is as below:\n");
575          * for(i=0; i< new_dsdt_length; i++){
576          *      printk_info("%x\t",(unsigned char)*(dsdt_pointer+i));
577          *      if( ((i+1)&0x7) == 0x0)
578          *              printk_info("**0x%x**\n",i-7);
579          *}
580          */
581
582         return 1;
583
584 }
585
586 unsigned long write_acpi_tables(unsigned long start)
587 {
588         unsigned long current;
589         acpi_rsdp_t *rsdp;
590         acpi_rsdt_t *rsdt;
591         acpi_hpet_t *hpet;
592         acpi_madt_t *madt;
593         acpi_fadt_t *fadt;
594         acpi_facs_t *facs;
595         acpi_header_t *dsdt;
596         acpi_header_t *ssdt;
597
598         get_bus_conf();         /* it will get sblk, pci1234, hcdn, and sbdn */
599
600         /* Align ACPI tables to 16byte */
601         start = (start + 0x0f) & -0x10;
602         current = start;
603
604         printk_info("ACPI: Writing ACPI tables at %lx...\n", start);
605
606         /* We need at least an RSDP and an RSDT Table */
607         rsdp = (acpi_rsdp_t *) current;
608         current += sizeof(acpi_rsdp_t);
609         rsdt = (acpi_rsdt_t *) current;
610         current += sizeof(acpi_rsdt_t);
611
612         /* clear all table memory */
613         memset((void *)start, 0, current - start);
614
615         acpi_write_rsdp(rsdp, rsdt);
616         acpi_write_rsdt(rsdt);
617
618         /*
619          * We explicitly add these tables later on:
620          */
621         /* If we want to use HPET Timers Linux wants an MADT */
622         printk_debug("ACPI:    * HPET\n");
623         hpet = (acpi_hpet_t *) current;
624         current += sizeof(acpi_hpet_t);
625         acpi_create_hpet(hpet);
626         acpi_add_table(rsdt, hpet);
627
628         printk_debug("ACPI:    * MADT\n");
629         madt = (acpi_madt_t *) current;
630         acpi_create_madt(madt);
631         current += madt->header.length;
632         acpi_add_table(rsdt, madt);
633
634 #if 0
635         /* SRAT */
636         printk_debug("ACPI:    * SRAT\n");
637         srat = (acpi_srat_t *) current;
638         acpi_create_srat(srat);
639         current += srat->header.length;
640         acpi_add_table(rsdt, srat);
641
642         /* SLIT */
643         printk_debug("ACPI:    * SLIT\n");
644         slit = (acpi_slit_t *) current;
645         acpi_create_slit(slit);
646         current += slit->header.length;
647         acpi_add_table(rsdt, slit);
648 #endif
649
650         /* SSDT */
651         printk_debug("ACPI:    * SSDT\n");
652         ssdt = (acpi_header_t *) current;
653         current += ((acpi_header_t *) AmlCode_ssdt)->length;
654         memcpy((void *)ssdt, (void *)AmlCode_ssdt,
655                ((acpi_header_t *) AmlCode_ssdt)->length);
656         /* Here you need to set value in pci1234, sblk and sbdn in get_bus_conf.c */
657         update_ssdt((void *)ssdt);
658         /* recalculate checksum */
659         ssdt->checksum = 0;
660         ssdt->checksum = acpi_checksum((u8 *)ssdt, ssdt->length);
661         acpi_add_table(rsdt, ssdt);
662
663 #if ACPI_SSDTX_NUM >= 1
664
665         /* same htio, but different position? We may have to copy, change HCIN, and recalculate the checknum and add_table */
666
667         for (i = 1; i < sysconf.hc_possible_num; i++) { /* 0: is hc sblink */
668                 if ((sysconf.pci1234[i] & 1) != 1)
669                         continue;
670                 uint8_t c;
671                 if (i < 7) {
672                         c = (uint8_t) ('4' + i - 1);
673                 } else {
674                         c = (uint8_t) ('A' + i - 1 - 6);
675                 }
676                 printk_debug("ACPI:    * SSDT for PCI%c Aka hcid = %d\n", c, sysconf.hcid[i]);  /* pci0 and pci1 are in dsdt */
677                 current = (current + 0x07) & -0x08;
678                 ssdtx = (acpi_header_t *) current;
679                 switch (sysconf.hcid[i]) {
680                 case 1: /* 8132 */
681                         p = AmlCode_ssdt2;
682                         break;
683                 case 2: /* 8151 */
684                         p = AmlCode_ssdt3;
685                         break;
686                 case 3: /* 8131 */
687                         p = AmlCode_ssdt4;
688                         break;
689                 default:
690                         /* HTX no io apic */
691                         p = AmlCode_ssdt5;
692                         break;
693                 }
694                 current += ((acpi_header_t *) p)->length;
695                 memcpy((void *)ssdtx, (void *)p, ((acpi_header_t *) p)->length);
696                 update_ssdtx((void *)ssdtx, i);
697                 ssdtx->checksum = 0;
698                 ssdtx->checksum =
699                     acpi_checksum((u8 *)ssdtx, ssdtx->length);
700                 acpi_add_table(rsdt, ssdtx);
701         }
702 #endif
703
704         /* FACS */
705         printk_debug("ACPI:    * FACS\n");
706         facs = (acpi_facs_t *) current;
707         current += sizeof(acpi_facs_t);
708         acpi_create_facs(facs);
709
710         /* DSDT */
711         printk_debug("ACPI:    * DSDT\n");
712         dsdt = (acpi_header_t *) current;
713         memcpy((void *)dsdt, (void *)AmlCode,
714                ((acpi_header_t *) AmlCode)->length);
715         if (!pstates_algorithm(dsdt))
716                 printk_debug("pstates_algorithm error!\n");
717         else
718                 printk_debug("pstates_algorithm success.\n");
719
720         current += dsdt->length;
721         printk_debug("ACPI:    * DSDT @ %08x Length %x\n", dsdt, dsdt->length);
722         /* FDAT */
723         printk_debug("ACPI:    * FADT\n");
724         fadt = (acpi_fadt_t *) current;
725         current += sizeof(acpi_fadt_t);
726
727         acpi_create_fadt(fadt, facs, dsdt);
728         acpi_add_table(rsdt, fadt);
729
730 #if DUMP_ACPI_TABLES == 1
731         printk_debug("rsdp\n");
732         dump_mem(rsdp, ((void *)rsdp) + sizeof(acpi_rsdp_t));
733
734         printk_debug("rsdt\n");
735         dump_mem(rsdt, ((void *)rsdt) + sizeof(acpi_rsdt_t));
736
737         printk_debug("madt\n");
738         dump_mem(madt, ((void *)madt) + madt->header.length);
739
740         printk_debug("srat\n");
741         dump_mem(srat, ((void *)srat) + srat->header.length);
742
743         printk_debug("slit\n");
744         dump_mem(slit, ((void *)slit) + slit->header.length);
745
746         printk_debug("ssdt\n");
747         dump_mem(ssdt, ((void *)ssdt) + ssdt->length);
748
749         printk_debug("fadt\n");
750         dump_mem(fadt, ((void *)fadt) + fadt->header.length);
751 #endif
752
753         printk_info("ACPI: done.\n");
754         return current;
755 }