diff --git a/sys/amd64/include/resource.h b/sys/amd64/include/resource.h --- a/sys/amd64/include/resource.h +++ b/sys/amd64/include/resource.h @@ -40,5 +40,6 @@ #define SYS_RES_MEMORY 3 /* i/o memory */ #define SYS_RES_IOPORT 4 /* i/o ports */ #define PCI_RES_BUS 5 /* PCI bus numbers */ +#define SYS_RES_FFH 6 /* FFixedhardware */ #endif /* !_MACHINE_RESOURCE_H_ */ diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -403,6 +403,7 @@ # config(8) doesn't have a way to force standard options, so we've been inconsistent # about marking non-optional things 'standard'. x86/acpica/madt.c optional acpi +x86/acpica/acpi_cppc_platform.c optional acpi x86/isa/atpic.c optional atpic isa x86/isa/elcr.c optional atpic isa | mptable x86/isa/isa.c standard diff --git a/sys/x86/acpica/acpi_cppc_platform.c b/sys/x86/acpica/acpi_cppc_platform.c new file mode 100644 --- /dev/null +++ b/sys/x86/acpica/acpi_cppc_platform.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +uint64_t +acpi_ffh_read(device_t dev, struct resource *res) +{ + uint64_t val; + + x86_msr_op(res->r_bushandle, + MSR_OP_RENDEZVOUS_ONE | MSR_OP_READ | + MSR_OP_CPUID(cpu_get_pcpu(dev)->pc_cpuid), + 0, &val); + return (val); +} + +void +acpi_ffh_write(device_t dev, struct resource *res, uint64_t val) +{ + x86_msr_op(res->r_bushandle, + MSR_OP_RENDEZVOUS_ONE | MSR_OP_WRITE | + MSR_OP_CPUID(cpu_get_pcpu(dev)->pc_cpuid), + val, NULL); +} diff --git a/sys/x86/include/bus.h b/sys/x86/include/bus.h --- a/sys/x86/include/bus.h +++ b/sys/x86/include/bus.h @@ -98,14 +98,16 @@ #define _MACHINE_BUS_H_ #include -#include #include +#include +#include /* * Values for the x86 bus space tag, not to be used directly by MI code. */ #define X86_BUS_SPACE_IO 0 /* space is i/o space */ #define X86_BUS_SPACE_MEM 1 /* space is mem space */ +#define X86_BUS_SPACE_FFH 2 /* space is mem space */ #define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF @@ -214,30 +216,33 @@ bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t offset) { - if (tag == X86_BUS_SPACE_IO) return (inb(handle + offset)); - return (*(volatile u_int8_t *)(handle + offset)); + if (tag == X86_BUS_SPACE_MEM) + return (*(volatile u_int8_t *)(handle + offset)); + return (BUS_SPACE_INVALID_DATA); } static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t offset) { - if (tag == X86_BUS_SPACE_IO) return (inw(handle + offset)); - return (*(volatile u_int16_t *)(handle + offset)); + if (tag == X86_BUS_SPACE_MEM) + return (*(volatile u_int16_t *)(handle + offset)); + return (BUS_SPACE_INVALID_DATA); } static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t offset) { - if (tag == X86_BUS_SPACE_IO) return (inl(handle + offset)); - return (*(volatile u_int32_t *)(handle + offset)); + if (tag == X86_BUS_SPACE_MEM) + return (*(volatile u_int32_t *)(handle + offset)); + return (BUS_SPACE_INVALID_DATA); } #ifdef __amd64__ @@ -245,8 +250,7 @@ bus_space_read_8(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t offset) { - - if (tag == X86_BUS_SPACE_IO) /* No 8 byte IO space access on x86 */ + if (tag != X86_BUS_SPACE_MEM) /* No 8 byte IO space access on x86 */ return (BUS_SPACE_INVALID_DATA); return (*(volatile uint64_t *)(handle + offset)); } @@ -278,7 +282,7 @@ if (tag == X86_BUS_SPACE_IO) insb(bsh + offset, addr, count); - else { + else if (tag == X86_BUS_SPACE_MEM) { __asm __volatile(" \n\ 1: movb (%2),%%al \n\ stosb \n\ @@ -296,7 +300,7 @@ if (tag == X86_BUS_SPACE_IO) insw(bsh + offset, addr, count); - else { + else if (tag == X86_BUS_SPACE_MEM) { __asm __volatile(" \n\ 1: movw (%2),%%ax \n\ stosw \n\ @@ -314,7 +318,7 @@ if (tag == X86_BUS_SPACE_IO) insl(bsh + offset, addr, count); - else { + else if (tag == X86_BUS_SPACE_MEM) { __asm __volatile(" \n\ 1: movl (%2),%%eax \n\ stosl \n\ @@ -364,7 +368,7 @@ "=D" (addr), "=c" (count), "=d" (_port_) : "0" (addr), "1" (count), "2" (_port_) : "%eax", "memory", "cc"); - } else { + } else if (tag == X86_BUS_SPACE_MEM) { bus_space_handle_t _port_ = bsh + offset; __asm __volatile(" \n\ repne \n\ @@ -390,7 +394,7 @@ "=D" (addr), "=c" (count), "=d" (_port_) : "0" (addr), "1" (count), "2" (_port_) : "%eax", "memory", "cc"); - } else { + } else if (tag == X86_BUS_SPACE_MEM) { bus_space_handle_t _port_ = bsh + offset; __asm __volatile(" \n\ repne \n\ @@ -416,7 +420,7 @@ "=D" (addr), "=c" (count), "=d" (_port_) : "0" (addr), "1" (count), "2" (_port_) : "%eax", "memory", "cc"); - } else { + } else if (tag == X86_BUS_SPACE_MEM) { bus_space_handle_t _port_ = bsh + offset; __asm __volatile(" \n\ repne \n\ @@ -461,7 +465,7 @@ if (tag == X86_BUS_SPACE_IO) outb(bsh + offset, value); - else + else if (tag == X86_BUS_SPACE_MEM) *(volatile u_int8_t *)(bsh + offset) = value; } @@ -472,7 +476,7 @@ if (tag == X86_BUS_SPACE_IO) outw(bsh + offset, value); - else + else if (tag == X86_BUS_SPACE_MEM) *(volatile u_int16_t *)(bsh + offset) = value; } @@ -483,7 +487,7 @@ if (tag == X86_BUS_SPACE_IO) outl(bsh + offset, value); - else + else if (tag == X86_BUS_SPACE_MEM) *(volatile u_int32_t *)(bsh + offset) = value; } @@ -495,7 +499,7 @@ if (tag == X86_BUS_SPACE_IO) /* No 8 byte IO space access on x86 */ return; - else + else if (tag == X86_BUS_SPACE_MEM) *(volatile uint64_t *)(bsh + offset) = value; } #endif @@ -529,7 +533,7 @@ if (tag == X86_BUS_SPACE_IO) outsb(bsh + offset, addr, count); - else { + else if (tag == X86_BUS_SPACE_MEM) { __asm __volatile(" \n\ 1: lodsb \n\ movb %%al,(%2) \n\ @@ -547,7 +551,7 @@ if (tag == X86_BUS_SPACE_IO) outsw(bsh + offset, addr, count); - else { + else if (tag == X86_BUS_SPACE_MEM) { __asm __volatile(" \n\ 1: lodsw \n\ movw %%ax,(%2) \n\ @@ -565,7 +569,7 @@ if (tag == X86_BUS_SPACE_IO) outsl(bsh + offset, addr, count); - else { + else if (tag == X86_BUS_SPACE_MEM) { __asm __volatile(" \n\ 1: lodsl \n\ movl %%eax,(%2) \n\ @@ -617,7 +621,7 @@ "=d" (_port_), "=S" (addr), "=c" (count) : "0" (_port_), "1" (addr), "2" (count) : "%eax", "memory", "cc"); - } else { + } else if (tag == X86_BUS_SPACE_MEM) { bus_space_handle_t _port_ = bsh + offset; __asm __volatile(" \n\ repne \n\ @@ -643,7 +647,7 @@ "=d" (_port_), "=S" (addr), "=c" (count) : "0" (_port_), "1" (addr), "2" (count) : "%eax", "memory", "cc"); - } else { + } else if (tag == X86_BUS_SPACE_MEM) { bus_space_handle_t _port_ = bsh + offset; __asm __volatile(" \n\ repne \n\ @@ -669,7 +673,7 @@ "=d" (_port_), "=S" (addr), "=c" (count) : "0" (_port_), "1" (addr), "2" (count) : "%eax", "memory", "cc"); - } else { + } else if (tag == X86_BUS_SPACE_MEM) { bus_space_handle_t _port_ = bsh + offset; __asm __volatile(" \n\ repne \n\ @@ -712,7 +716,7 @@ if (tag == X86_BUS_SPACE_IO) while (count--) outb(addr, value); - else + else if (tag == X86_BUS_SPACE_MEM) while (count--) *(volatile u_int8_t *)(addr) = value; } @@ -726,7 +730,7 @@ if (tag == X86_BUS_SPACE_IO) while (count--) outw(addr, value); - else + else if (tag == X86_BUS_SPACE_MEM) while (count--) *(volatile u_int16_t *)(addr) = value; } @@ -740,7 +744,7 @@ if (tag == X86_BUS_SPACE_IO) while (count--) outl(addr, value); - else + else if (tag == X86_BUS_SPACE_MEM) while (count--) *(volatile u_int32_t *)(addr) = value; } @@ -776,7 +780,7 @@ if (tag == X86_BUS_SPACE_IO) for (; count != 0; count--, addr++) outb(addr, value); - else + else if (tag == X86_BUS_SPACE_MEM) for (; count != 0; count--, addr++) *(volatile u_int8_t *)(addr) = value; } @@ -790,7 +794,7 @@ if (tag == X86_BUS_SPACE_IO) for (; count != 0; count--, addr += 2) outw(addr, value); - else + else if (tag == X86_BUS_SPACE_MEM) for (; count != 0; count--, addr += 2) *(volatile u_int16_t *)(addr) = value; } @@ -804,7 +808,7 @@ if (tag == X86_BUS_SPACE_IO) for (; count != 0; count--, addr += 4) outl(addr, value); - else + else if (tag == X86_BUS_SPACE_MEM) for (; count != 0; count--, addr += 4) *(volatile u_int32_t *)(addr) = value; } @@ -855,7 +859,7 @@ count != 0; count--, addr1--, addr2--) outb(addr2, inb(addr1)); } - } else { + } else if (tag == X86_BUS_SPACE_MEM) { if (addr1 >= addr2) { /* src after dest: copy forward */ for (; count != 0; count--, addr1++, addr2++) @@ -890,7 +894,7 @@ count != 0; count--, addr1 -= 2, addr2 -= 2) outw(addr2, inw(addr1)); } - } else { + } else if (tag == X86_BUS_SPACE_MEM) { if (addr1 >= addr2) { /* src after dest: copy forward */ for (; count != 0; count--, addr1 += 2, addr2 += 2) @@ -925,7 +929,7 @@ count != 0; count--, addr1 -= 4, addr2 -= 4) outl(addr2, inl(addr1)); } - } else { + } else if (tag == X86_BUS_SPACE_MEM) { if (addr1 >= addr2) { /* src after dest: copy forward */ for (; count != 0; count--, addr1 += 4, addr2 += 4) diff --git a/sys/x86/x86/nexus.c b/sys/x86/x86/nexus.c --- a/sys/x86/x86/nexus.c +++ b/sys/x86/x86/nexus.c @@ -85,7 +85,7 @@ #define DEVTONX(dev) ((struct nexus_device *)device_get_ivars(dev)) -struct rman irq_rman, drq_rman, port_rman, mem_rman; +struct rman irq_rman, drq_rman, port_rman, mem_rman, ffh_rman; static int nexus_print_all_resources(device_t dev); @@ -253,6 +253,14 @@ if (rman_init(&mem_rman) || rman_manage_region(&mem_rman, 0, mem_rman.rm_end)) panic("nexus_init_resources mem_rman"); + + ffh_rman.rm_start = 0; + ffh_rman.rm_end = 0xffffffff; + ffh_rman.rm_type = RMAN_ARRAY; + ffh_rman.rm_descr = "FFH (MSR)"; + if (rman_init(&ffh_rman) || + rman_manage_region(&ffh_rman, 0, 0xffffffff)) + panic("nexus_init_resources ffg_rman"); } static int @@ -286,6 +294,7 @@ retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#jx"); retval += resource_list_print_type(rl, "iomem", SYS_RES_MEMORY, "%#jx"); retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%jd"); + retval += resource_list_print_type(rl, "ffh", SYS_RES_FFH, "%jd"); return (retval); } @@ -335,6 +344,8 @@ return (&port_rman); case SYS_RES_MEMORY: return (&mem_rman); + case SYS_RES_FFH: + return (&ffh_rman); default: return (NULL); } @@ -385,11 +396,13 @@ if (!(rman_get_flags(r) & RF_ACTIVE)) return (ENXIO); - /* Mappings are only supported on I/O and memory resources. */ + /* Mappings are only supported on I/O, memory and FFixedhardware + * resources. */ type = rman_get_type(r); switch (type) { case SYS_RES_IOPORT: case SYS_RES_MEMORY: + case SYS_RES_FFH: break; default: return (EINVAL); @@ -420,6 +433,11 @@ */ map->r_bushandle = (bus_space_handle_t)map->r_vaddr; break; + case SYS_RES_FFH: + map->r_bushandle = start; + map->r_bustag = X86_BUS_SPACE_FFH; + map->r_size = length; + break; } return (0); } @@ -436,6 +454,7 @@ case SYS_RES_MEMORY: pmap_unmapdev(map->r_vaddr, map->r_size); /* FALLTHROUGH */ + case SYS_RES_FFH: case SYS_RES_IOPORT: break; default: