This patch is made by Masanori Kanaoka. Slightly cleaned up by me. Index: arch/i386/acpi/vald_acpi.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/acpi/vald_acpi.c,v retrieving revision 1.5 diff -u -r1.5 vald_acpi.c --- arch/i386/acpi/vald_acpi.c 2002/10/02 05:47:11 1.5 +++ arch/i386/acpi/vald_acpi.c 2003/03/30 09:59:44 @@ -447,9 +447,17 @@ } } if (sc->sc_ac_status == 1) /* AC adaptor on when attach */ +#ifndef LIBRETTO sc->lcd_index = sc->lcd_num -1; /* MAX Brightness */ +#else + sc->lcd_index = 3; /* MAX Brightness */ +#endif else +#ifndef LIBRETTO sc->lcd_index = 3; +#else + sc->lcd_index = 2; +#endif #ifdef ACPI_DEBUG pi = sc->lcd_level; Index: arch/i386/i386/autoconf.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/i386/autoconf.c,v retrieving revision 1.68 diff -u -r1.68 autoconf.c --- arch/i386/i386/autoconf.c 2003/03/22 13:05:26 1.68 +++ arch/i386/i386/autoconf.c 2003/03/30 09:59:45 @@ -99,12 +99,14 @@ #include #endif +#ifndef LIBRETTO #include "opt_pcibios.h" #ifdef PCIBIOS #include #include #include #endif +#endif /* LIBRETTO */ #include "opt_kvm86.h" #ifdef KVM86 @@ -126,9 +128,11 @@ #if NBIOS32 > 0 bios32_init(); #endif +#ifndef LIBRETTO #ifdef PCIBIOS pcibios_init(); #endif +#endif /* LIBRETTO */ /* kvm86 needs a TSS */ i386_proc0_tss_ldt_init(); Index: arch/i386/i386/machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/i386/machdep.c,v retrieving revision 1.517 diff -u -r1.517 machdep.c --- arch/i386/i386/machdep.c 2003/03/25 19:37:16 1.517 +++ arch/i386/i386/machdep.c 2003/03/30 09:59:48 @@ -1641,6 +1641,13 @@ } } #endif /* ! REALBASEMEM && ! REALEXTMEM */ + +#ifdef LIBRETTO +#ifdef DEBUG_MEMLOAD + printf("mem_cluster_count: %d\n", mem_cluster_cnt); +#endif +#endif + /* * If the loop above didn't find any valid segment, fall back to * former code. Index: arch/i386/i386/mainbus.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/i386/mainbus.c,v retrieving revision 1.50 diff -u -r1.50 mainbus.c --- arch/i386/i386/mainbus.c 2003/03/04 01:06:38 1.50 +++ arch/i386/i386/mainbus.c 2003/03/30 09:59:48 @@ -55,6 +55,15 @@ #include "acpi.h" #include "vesabios.h" +#ifdef LIBRETTO +#include "opt_pcibios.h" +#ifdef PCIBIOS +#include +#include +#include +#endif +#endif /* LIBRETTO */ + #include "opt_mpacpi.h" #include "opt_mpbios.h" @@ -278,6 +287,12 @@ config_found(self, &mba.mba_paa, mainbus_print); } #endif + +#ifdef LIBRETTO +#ifdef PCIBIOS + pcibios_init(); +#endif +#endif /* LIBRETTO */ /* * XXX Note also that the presence of a PCI bus should Index: arch/i386/pci/pci_intr_fixup.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/pci/pci_intr_fixup.c,v retrieving revision 1.23 diff -u -r1.23 pci_intr_fixup.c --- arch/i386/pci/pci_intr_fixup.c 2003/02/26 22:23:08 1.23 +++ arch/i386/pci/pci_intr_fixup.c 2003/03/30 09:59:49 @@ -571,10 +571,20 @@ { int i, bit; +#ifdef LIBRETTO + /* XXX: Force set Level for some irq (such as ACPI SCI) */ + *pciirq |= pcibios_force_level_bitmap; +#endif /* LIBRETTO */ + for (i = 0, bit = 1; i < 16; i++, bit <<= 1) { if ((*pciirq & bit) == 0) (void) pciintr_icu_set_trigger(pciintr_icu_tag, pciintr_icu_handle, i, IST_EDGE); +#ifdef LIBRETTO + else if (pcibios_force_level_bitmap & bit) + (void) pciintr_icu_set_trigger(pciintr_icu_tag, + pciintr_icu_handle, i, IST_LEVEL); +#endif /* LIBRETTO */ } return (0); Index: arch/i386/pci/pcibios.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/pci/pcibios.c,v retrieving revision 1.11 diff -u -r1.11 pcibios.c --- arch/i386/pci/pcibios.c 2003/02/26 22:23:09 1.11 +++ arch/i386/pci/pcibios.c 2003/03/30 09:59:49 @@ -83,6 +83,10 @@ #include #include +#ifdef LIBRETTO +#include +#endif /* LIBRETTO */ + #include #ifdef PCIBIOS_INTR_FIXUP #include @@ -126,6 +130,19 @@ #define PCI_IRQ_TABLE_START 0xf0000 #define PCI_IRQ_TABLE_END 0xfffff +#ifdef LIBRETTO +/* for Libretto L2/L3 hack */ +void pcibios_fixup_pir_table __P((void)); +void pcibios_fixup_pir_table_mask __P((struct pcibios_linkmap *)); + +struct pcibios_linkmap pir_mask[] = { + { 2, 0x0040 }, + { 7, 0x0080 }, + { 8, 0x0020 }, + { 0, 0x0000 } +}; +#endif /* LIBRETTO */ + static void pci_bridge_hook(pci_chipset_tag_t, pcitag_t, void *); struct pci_bridge_hook_arg { void (*func)(pci_chipset_tag_t, pcitag_t, void *); @@ -237,7 +254,62 @@ u_int16_t tablesize; u_int8_t rev_maj, rev_min; int i; +#ifdef LIBRETTO + struct pcibios_intr_routing *pir; + struct acpi_intr *ai; +#endif /* LIBRETTO */ + +#ifdef LIBRETTO + /* + * XXXlibretto + * For Libretto L series, we firstly try using ACPI PRT. + * This is done when the ACPI_PIR_GET option is set. + */ + pcibios_force_level_bitmap = 0; + if (acpi_pir_info != NULL && acpi_pir_info->api_nentries != 0) { + pcibios_pir_table = malloc(acpi_pir_info->api_nentries * 16, + M_DEVBUF, M_NOWAIT); + if (pcibios_pir_table == NULL) { + printf("pcibios_pir_init: no memory for $PIR\n"); + return; + } + for (ai = acpi_pir_info->api_intr, pir = pcibios_pir_table; + ai; + ai = ai->ai_next, pir++) { + pir->bus = ai->ai_bus; + pir->device = (ai->ai_dev & 0x1f) << 3; + for (i = 0; i < 4; i++) { + if (i == ai->ai_pin) { + pir->linkmap[i].link = ai->ai_link; + pir->linkmap[i].bitmap = ai->ai_bitmap; + } else { + pir->linkmap[i].link = 0; + pir->linkmap[i].bitmap = 0; + } + } + pir->slot = 0; + pir->reserved = 0; + } + pcibios_pir_table_nentries = acpi_pir_info->api_nentries; + pcibios_force_level_bitmap = (1 << acpi_pir_info->api_sci_irq); + printf("\nUsing ACPI PRT information.\n"); + + /* + * XXXlibretto + * For Libretto L2/L3. + */ + pcibios_fixup_pir_table(); +#ifdef PCIINTR_DEBUG + pcibios_print_pir_table(); +#endif + return; + } + /* + * XXXlibretto + * If no ACPI PRT is found, try using $PIR table. + */ +#endif /* LIBRETTO */ for (pa = PCI_IRQ_TABLE_START; pa < PCI_IRQ_TABLE_END; pa += 16) { p = (caddr_t)ISA_HOLE_VADDR(pa); if (*(int *)p != BIOS32_MAKESIG('$', 'P', 'I', 'R')) { @@ -301,6 +373,10 @@ } printf("\n"); pcibios_print_exclirq(); +#ifdef LIBRETTO + /* for Libretto L2/L3 hack */ + pcibios_fixup_pir_table(); +#endif /* LIBRETTO */ #ifdef PCIINTR_DEBUG pcibios_print_pir_table(); #endif @@ -333,6 +409,10 @@ printf("PCI BIOS has %d Interrupt Routing table entries\n", pcibios_pir_table_nentries); pcibios_print_exclirq(); +#ifdef LIBRETTO + /* for Libretto L2/L3 hack */ + pcibios_fixup_pir_table(); +#endif #ifdef PCIINTR_DEBUG pcibios_print_pir_table(); #endif @@ -477,6 +557,35 @@ printf("\n"); } } + +#ifdef LIBRETTO +/* for Libretto L2/L3 hack */ +void +pcibios_fixup_pir_table() +{ + struct pcibios_linkmap *m; + + for (m = pir_mask; m->link != 0; m++) + pcibios_fixup_pir_table_mask(m); +} + +void +pcibios_fixup_pir_table_mask(mask) + struct pcibios_linkmap *mask; +{ + int i, j; + + for (i = 0; i < pcibios_pir_table_nentries; i++) { + for (j = 0; j < 4; j++) { + if (pcibios_pir_table[i].linkmap[j].link == + mask->link) { + pcibios_pir_table[i].linkmap[j].bitmap + &= mask->bitmap; + } + } + } +} +#endif /* LIBRETTO */ #ifdef PCIINTR_DEBUG void Index: arch/i386/pci/pcibios.h =================================================================== RCS file: /cvsroot/src/sys/arch/i386/pci/pcibios.h,v retrieving revision 1.5 diff -u -r1.5 pcibios.h --- arch/i386/pci/pcibios.h 2002/01/22 15:07:27 1.5 +++ arch/i386/pci/pcibios.h 2003/03/30 09:59:49 @@ -100,6 +100,10 @@ void pci_bridge_foreach(pci_chipset_tag_t, int, int, void (*) (pci_chipset_tag_t, pcitag_t, void *), void *); +#ifdef LIBRETTO +u_int16_t pcibios_force_level_bitmap; +#endif + #ifdef PCIBIOSVERBOSE extern int pcibiosverbose; Index: dev/acpi/acpi.c =================================================================== RCS file: /cvsroot/src/sys/dev/acpi/acpi.c,v retrieving revision 1.33 diff -u -r1.33 acpi.c --- dev/acpi/acpi.c 2003/03/05 23:00:56 1.33 +++ dev/acpi/acpi.c 2003/03/30 09:59:52 @@ -60,18 +60,32 @@ #include #endif +#ifndef LIBRETTO #ifndef ACPI_PCI_FIXUP #define ACPI_PCI_FIXUP 1 #endif +#else /* LIBRETTO */ +#ifndef ACPI_PCI_GET +#define ACPI_PCI_GET 1 +#endif +#endif /* LIBRETTO */ #ifndef ACPI_ACTIVATE_DEV #define ACPI_ACTIVATE_DEV 0 #endif +#ifndef LIBRETTO #if ACPI_PCI_FIXUP #include /* AcpiNsGetNodeByPath() */ #include #endif +#else +#if ACPI_PCI_GET +#include +#include /* AcpiNsGetNodeByPath() */ +#include +#endif +#endif /* LIBRETTO */ MALLOC_DECLARE(M_ACPI); @@ -125,12 +139,18 @@ ACPI_STATUS acpi_make_devnode(ACPI_HANDLE, UINT32, void *, void **); void acpi_enable_fixed_events(struct acpi_softc *); +#ifndef LIBRETTO #if ACPI_PCI_FIXUP void acpi_pci_fixup(struct acpi_softc *); #endif #if ACPI_PCI_FIXUP || ACPI_ACTIVATE_DEV ACPI_STATUS acpi_allocate_resources(ACPI_HANDLE handle); #endif +#else /* LIBRETTO */ +#if ACPI_PCI_GET +void acpi_pir_get(struct acpi_softc *); +#endif +#endif /* LIBRETTO */ /* * acpi_probe: @@ -311,12 +331,19 @@ */ acpi_enable_fixed_events(sc); +#ifndef LIBRETTO /* * Fix up PCI devices. */ #if ACPI_PCI_FIXUP acpi_pci_fixup(sc); #endif +#else /* LIBRETTO */ +#if ACPI_PIR_GET + /* Get PCI IRQ ROUTING table. */ + acpi_pir_get(sc); +#endif /* ACPI_PIR_GET */ +#endif /* LIBRETTO */ /* * Scan the namespace and build our device tree. @@ -810,6 +837,15 @@ bufp->Length = ACPI_ALLOCATE_BUFFER; rv = AcpiEvaluateObject(handle, path, NULL, bufp); +#ifdef MY + /* XXXuebayasi */ + if (rv == AE_BUFFER_OVERFLOW) { + bufp->Pointer = AcpiOsAllocate(bufp->Length); + if (bufp->Pointer == NULL) + return (AE_NO_MEMORY); + rv = AcpiEvaluateObject(handle, path, NULL, bufp); + } +#endif /* MY */ return (rv); } @@ -986,6 +1022,7 @@ return (ret); } +#ifdef LIBRETTO #if ACPI_PCI_FIXUP ACPI_STATUS acpi_pci_fixup_bus(ACPI_HANDLE, UINT32, void *, void **); /* @@ -1010,7 +1047,36 @@ AcpiWalkNamespace(ACPI_TYPE_DEVICE, parent, 100, acpi_pci_fixup_bus, sc, NULL); } +#endif /* ACPI_PCI_FIXUP */ +#else /* LIBRETTO */ +#if ACPI_PIR_GET +ACPI_STATUS acpi_pir_get_bus(ACPI_HANDLE, UINT32, void *, void **); +/* + * XXXlibretto + * acpi_pir_get: + * + * Get the _PTR (PCI Routing Table), and create an ACPI PIR table + * which PCIBIOS_INTR_FIXUP will use later. + */ +void +acpi_pir_get(struct acpi_softc *sc) +{ + ACPI_HANDLE parent; + +#ifdef ACPI_DEBUG + printf("acpi_pir_get starts:\n"); +#endif + if (AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SB_", &parent) != AE_OK) + return; + sc->sc_pci_bus = 0; + AcpiWalkNamespace(ACPI_TYPE_DEVICE, parent, 100, + acpi_pir_get_bus, sc, NULL); +} +#endif /* ACPI_PIR_GET */ +#endif /* LIBRETTO */ +#ifndef LIBRETTO +#if ACPI_PCI_FIXUP static ACPI_HANDLE acpi_get_node(char *name) { @@ -1152,7 +1218,7 @@ sc->sc_pci_bus, level); #endif - for (Buffer = buf.Pointer; ; Buffer += PrtElement->Length) { + for (Buffer = buf.Pointer;; Buffer += PrtElement->Length) { PrtElement = (ACPI_PCI_ROUTING_TABLE *)Buffer; if (PrtElement->Length == 0) break; @@ -1192,7 +1258,121 @@ return (AE_OK); } #endif /* ACPI_PCI_FIXUP */ +#else /* LIBRETTO */ +#if ACPI_PIR_GET +static UINT16 +acpi_get_bitmap(ACPI_HANDLE handle) +{ + ACPI_BUFFER bufp, bufc; + ACPI_STATUS rv; + ACPI_RESOURCE *resp, *resc; + ACPI_RESOURCE_IRQ *irq; + UINT16 i, bitmap = 0; + + rv = acpi_get(handle, &bufp, AcpiGetPossibleResources); + if (ACPI_FAILURE(rv)) + goto out; + rv = acpi_get(handle, &bufc, AcpiGetCurrentResources); + if (ACPI_FAILURE(rv)) + goto out1; + + resp = bufp.Pointer; + resc = bufc.Pointer; + + /* + * If current NumberOfInterrupt is 1, we use it. + * Else we use possible. + */ + irq = (ACPI_RESOURCE_IRQ *)&resc->Data; + if (irq->NumberOfInterrupts != 1) + irq = (ACPI_RESOURCE_IRQ *)&resp->Data; + + for (i = 0; i < irq->NumberOfInterrupts; i++) + bitmap |= (1 << irq->Interrupts[i]); + + free(bufc.Pointer, M_DEVBUF); +out1: + free(bufp.Pointer, M_DEVBUF); +out: + return (bitmap); +} + +ACPI_STATUS +acpi_pir_get_bus(ACPI_HANDLE handle, UINT32 level, void *context, + void **status) +{ + struct acpi_softc *sc = context; + ACPI_STATUS rv; + ACPI_BUFFER buf; + UINT8 *Buffer; + ACPI_PCI_ROUTING_TABLE *PrtElement; + ACPI_HANDLE link; + char LastChar; + UINT16 bitmap; + struct acpi_intr *ai; + + rv = acpi_get(handle, &buf, AcpiGetIrqRoutingTable); + if (ACPI_FAILURE(rv)) + return (AE_OK); + + acpi_pir_info = malloc(sizeof(struct acpi_pir), M_DEVBUF, M_NOWAIT); + if (acpi_pir_info == NULL) { + printf("No memory for acpi_pir_info\n"); + return (AE_OK); + } + acpi_pir_info->api_intr = NULL; + acpi_pir_info->api_nentries = 0; + acpi_pir_info->api_sci_irq = AcpiGbl_FADT->SciInt; + + for (Buffer = buf.Pointer;; Buffer += PrtElement->Length) { + PrtElement = (ACPI_PCI_ROUTING_TABLE *)Buffer; + if (PrtElement->Length == 0) + break; + if (PrtElement->Source == NULL) + continue; + + link = acpi_get_node(PrtElement->Source); + if (link == NULL) + continue; + bitmap = acpi_get_bitmap(link); + + LastChar = PrtElement->Source[strlen(PrtElement->Source) - 1]; + if (LastChar >= 'A' && LastChar <= 'Z') + LastChar -= '@'; + else if (LastChar >= '0' && LastChar <= '9') + LastChar -= '0'; + +#ifdef ACPI_DEBUG + printf("\tBus: %d Device: %d\n ", sc->sc_pci_bus, + (unsigned)PrtElement->Address >> 16); + printf("\t\tINT%c: link 0x%02x bitmap 0x%04x\n", + PrtElement->Pin + 1 + '@', LastChar, bitmap); +#endif + /* XXX: make pcibios Interface. */ + ai = malloc(sizeof(*ai), M_DEVBUF, M_NOWAIT); + if (ai == NULL) { + printf("No memory for ai\n"); + return (AE_OK); + } + ai->ai_next = acpi_pir_info->api_intr; + ai->ai_bus = sc->sc_pci_bus; + ai->ai_dev = (unsigned)PrtElement->Address >> 16; + ai->ai_pin = PrtElement->Pin; + ai->ai_link = LastChar; + ai->ai_bitmap = bitmap; + acpi_pir_info->api_intr = ai; + acpi_pir_info->api_nentries++; + } + + sc->sc_pci_bus++; + + free(buf.Pointer, M_DEVBUF); + return (AE_OK); +} +#endif /* ACPI_PIR_GET */ +#endif /* LIBRETTO */ +#ifndef LIBRETTO #if ACPI_PCI_FIXUP || ACPI_ACTIVATE_DEV /* XXX This very incomplete */ ACPI_STATUS @@ -1279,3 +1459,4 @@ return rv; } #endif /* ACPI_PCI_FIXUP || ACPI_ACTIVATE_DEV */ +#endif /* LIBRETTO */ Index: dev/acpi/acpivar.h =================================================================== RCS file: /cvsroot/src/sys/dev/acpi/acpivar.h,v retrieving revision 1.9 diff -u -r1.9 acpivar.h --- dev/acpi/acpivar.h 2003/02/14 11:05:40 1.9 +++ dev/acpi/acpivar.h 2003/03/30 09:59:52 @@ -268,6 +268,25 @@ struct acpi_irq *acpi_res_irq(struct acpi_resources *, int); struct acpi_drq *acpi_res_drq(struct acpi_resources *, int); +#ifdef LIBRETTO +struct acpi_intr { + struct acpi_intr *ai_next; + u_int8_t ai_bus; + u_int8_t ai_dev; + u_int8_t ai_pin; + u_int8_t ai_link; + u_int16_t ai_bitmap; +}; + +struct acpi_pir { + struct acpi_intr *api_intr; + int api_nentries; + int api_sci_irq; +}; + +struct acpi_pir *acpi_pir_info; +#endif /* LIBRETTO */ + /* * power state transition */ Index: dev/ic/ac97.c =================================================================== RCS file: /cvsroot/src/sys/dev/ic/ac97.c,v retrieving revision 1.41 diff -u -r1.41 ac97.c --- dev/ic/ac97.c 2003/03/03 02:14:12 1.41 +++ dev/ic/ac97.c 2003/03/30 09:59:54 @@ -658,6 +658,10 @@ #define DPRINTFN(n,x) #endif +#ifdef LIBRETTO +static int ac97_waitthrough; +#endif + void ac97_read(as, reg, val) struct ac97_softc *as; @@ -665,9 +669,15 @@ u_int16_t *val; { +#ifndef LIBRETTO if (as->host_flags & AC97_HOST_DONT_READ && (reg != AC97_REG_VENDOR_ID1 && reg != AC97_REG_VENDOR_ID2 && reg != AC97_REG_RESET)) { +#else + if (reg != AC97_REG_VENDOR_ID1 && + reg != AC97_REG_VENDOR_ID2 && + reg != AC97_REG_RESET) { +#endif /* LIBRETTO */ *val = as->shadow_reg[reg >> 1]; return; } @@ -684,6 +694,11 @@ u_int16_t val; { +#ifdef LIBRETTO + if (ac97_waitthrough == 0 && as->shadow_reg[reg >> 1] == val) + return (0); +#endif + as->shadow_reg[reg >> 1] = val; return (as->host_if->write(as->host_if->arg, reg, val)); @@ -697,11 +712,17 @@ const struct ac97_source_info *si; memset(as->shadow_reg, 0, sizeof(as->shadow_reg)); +#ifdef LIBRETTO + ac97_waitthrough = 1; +#endif for (idx = 0; idx < SOURCE_INFO_SIZE; idx++) { si = &source_info[idx]; ac97_write(as, si->reg, si->default_value); } +#ifdef LIBRETTO + ac97_waitthrough = 0; +#endif } void @@ -712,10 +733,16 @@ int idx; const struct ac97_source_info *si; +#ifdef LIBRETTO + ac97_waitthrough = 1; +#endif for (idx = 0; idx < SOURCE_INFO_SIZE; idx++) { si = &source_info[idx]; ac97_write(as, si->reg, as->shadow_reg[si->reg >> 1]); } +#ifdef LIBRETTO + ac97_waitthrough = 0; +#endif } int